Andreas Huber 对这个问题的回答让我想到了Concurrent<T>
使用异步委托而不是线程池来实现。但是,我发现更难理解将 anAsyncCallback
传递给时发生了什么BeginInvoke
,尤其是当多个线程可以访问IAsyncResult
. 不幸的是,MSDN 或我能找到的任何地方似乎都没有涵盖这种情况。此外,我能找到的所有文章要么是在闭包和泛型可用之前编写的,要么看起来就是这样。有几个问题(我希望答案是真的,但我准备好失望了):
1) 使用闭包作为 AsyncCallback 会有什么不同吗?
(希望不是)
2)如果一个线程在等待AsyncWaitHandle
,它会
在回调开始之前或 b)在它完成之后发出信号吗?
(希望是b)
3)当回调运行时,会IsCompleted
返回什么?我可以看到的可能性:
a)true
;b) false
; c)false
在回调调用 EndInvoke 之前,true
之后。
(希望是 b 或 c)
4)DisposedObjectException
如果某个线程在调用AsyncWaitHandle
之后等待会被抛出EndInvoke
?
(希望不是,但我希望是的)。
如果答案如我所愿,这似乎应该有效:
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 的答案是我所希望的,那么据我所知,这里应该没有种族条件。