Andreas Huber对this question的回答让我想到了使用异步委托实现Concurrent<T>
而不是ThreadPool。但是,当AsyncCallback
传递给BeginInvoke
时,我发现很难理解发生了什么,特别是当多个线程可以访问IAsyncResult
时。不幸的是,这种情况似乎没有涵盖在MSDN或任何我能找到的地方。而且,我能找到的所有文章都是在关闭和泛型可用之前编写的,或者看起来就是这样。有几个问题(我希望是真实的答案,但我准备好失望):以多线程方式使用BeginInvoke/EndInvoke。 AsyncCallback,AsyncWaitHandle和IsCompleted如何交互?
1)使用闭包作为AsyncCallback有什么区别?
(但愿不是)
2)如果在AsyncWaitHandle
一个线程等待,将它标志着
一)回调开始或 B)为完成后过吗?
(希望b)
3)当回调正在运行时,IsCompleted
会返回什么?可能性我可以看到:
a)true
; b)false
; c)false
之前的回调调用EndInvoke,true
之后。
(希望是b或c)
4)如果线程在调用EndInvoke
之后等待AsyncWaitHandle
会抛出?
(希望不是,但我希望是)。
提供的答案是,因为我希望,这似乎像它应该工作:
public class Concurrent<T> {
private IAsyncResult _asyncResult;
private T _result;
public Concurrent(Func<T> f) { // Assume f doesn't throw exceptions
_asyncResult = f.BeginInvoke(
asyncResult => {
// Assume assignment of T is atomic
_result = f.EndInvoke(asyncResult);
}, null);
}
public T Result {
get {
if (!_asyncResult.IsCompleted)
// Is there a race condition here?
_asyncResult.AsyncWaitHandle.WaitOne();
return _result; // Assume reading of T is atomic
}
...
如果问题的答案1-3都是我希望,应该在这里没有raace条件,据我所见。
尽管如果我想在这里实现IAsyncResult,那么您的答案将非常适用,但我不这样做。我在询问有关System.Runtime.Remoting.Messaging.AsyncResult的行为,这是BeginInvoke实际返回的行为。 – 2009-01-02 15:04:58