正确地使用单个扩展方法开始和结束调用。
我想与他人仔细检查这是否是创建开始异步过程的扩展方法并返回一个函数的正确方法,该函数在调用时实质上等待该过程并获取结果。
public static Func<R> HandleInvoke<T, R>(this Func<T, R> function, T arg, Action<IAsyncResult> callback)
{
IAsyncResult result = function.BeginInvoke(arg, new AsyncCallback(callback), function);
return delegate
{
return function.EndInvoke(result);
};
}
本质上,我想这样使用(伪代码):
Func<R> myFunc = (some delegate).HandleInvoke(arg, callback);
// at this point the operation begins, but will be nonblocking
// do other stuff
var result = myFunc(); // now I am deciding to wait on the result, which is blocking
不知道是否需要在这种情况下等待WaitHandles。也不确定是否甚至需要传递回调。我也认为这构成了关闭?
编辑
最后,
public static Func<R> HandleInvoke<T, R>(this Func<T, R> function, T arg)
{
IAsyncResult asyncResult = function.BeginInvoke(arg, iAsyncResult =>
{
if (!(iAsyncResult as AsyncResult).EndInvokeCalled)
{
(iAsyncResult.AsyncState as Func<T, R>).EndInvoke(iAsyncResult);
}
}, function);
return delegate
{
WaitHandle.WaitAll(new WaitHandle[] { asyncResult.AsyncWaitHandle });
return function.EndInvoke(asyncResult);
};
}
这似乎运作良好。回调检查是否已调用EndInvoke,如果未调用,则调用它。否则,在返回的委托中调用EndInvoke。
第二编辑
这是我的最新尝试-尚未向我抛出任何错误,并且似乎处理得很好。我无法在委托返回函数.EndInvoke()结果的地方使用它,但是委托在返回R之前一直等到匿名回调中已调用EndInvoke为止。Thread.Sleep()可能不是最佳解决方案。也可以使用更多检查来确保在每种情况下都已实际分配R。
public static Func<R> HandleInvoke<T, R>(this Func<T, R> function, T arg)
{
R r = default(R);
IAsyncResult asyncResult = function.BeginInvoke(arg, result =>
{
r = (result.AsyncState as Func<T, R>).EndInvoke(result);
}, function);
return delegate
{
while (!(asyncResult as AsyncResult).EndInvokeCalled)
{
Thread.Sleep(1);
}
return r;
};
}
没有找到相关结果
已邀请:
2 个回复
玩翁文醚碱
温拎凯玛
对于一个动作,它几乎是相同的:
但是,如果您不需要结果,则ThreadPool.QueueUserWorkItem()会更高效。