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