gpt4 book ai didi

c# - 以多线程方式使用 BeginInvoke/EndInvoke。 AsyncCallback、AsyncWaitHandle 和 IsCompleted 如何交互?

转载 作者:太空狗 更新时间:2023-10-30 01:28:31 25 4
gpt4 key购买 nike

Andreas Huber 对 this question 的回答给了我一个实现的想法 Concurrent<T>使用异步委托(delegate)而不是线程池。但是,我发现很难理解 AsyncCallback 时发生了什么。传递给 BeginInvoke ,尤其是当多个线程可以访问 IAsyncResult 时.不幸的是,MSDN 或我能找到的任何地方似乎都没有涉及这种情况。此外,我能找到的所有文章要么是在闭包和泛型可用之前写的,要么就是看起来那样。有几个问题(我希望答案是正确的,但我已经准备好失望了):

1) 使用闭包作为 AsyncCallback 会有什么不同吗?
(希望不会)
2) 如果线程等待 AsyncWaitHandle , 会不会发出信号
a) 在回调开始前或b) 完成后?
(希望是)
3)当回调运行时,IsCompleted会是什么?返回?我能看到的可能性:
一)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 的答案是我所希望的,那么据我所知,这里应该没有竞争条件。

最佳答案

问题一

我认为部分问题在于误解。 IAsyncResult 不会从多个线程访问,除非您明确地将其传递给一个线程。如果您查看 BCL 中 mos Begin*** 样式 API 的实现,您会注意到 IAsyncResult 仅在实际发生 Begin*** 或 End*** 调用的线程中创建和销毁。

问题二

AsyncWaitHandle 应在操作 100% 完成后发出信号。

问题三

IsCompleted 应该在底层操作完成后返回 true(没有更多工作要做)。查看 IsComplete 的最佳方式是,如果值为

  1. true -> Calling End*** 会立即返回
  2. false -> Callind End*** 会阻塞一段时间

问题 4

这取决于实现。这里没有办法真正给出一个笼统的答案。

示例

如果您对允许您轻松地在另一个线程上运行委托(delegate)并在完成时访问结果的 API 感兴趣,请查看我的 RantPack Utility Library .它以源代码和二进制形式提供。它有一个完全充实的 Future API,允许并发运行委托(delegate)。

另外还有一个 IAsyncResult 的实现,它涵盖了本文中的大部分问题。

关于c# - 以多线程方式使用 BeginInvoke/EndInvoke。 AsyncCallback、AsyncWaitHandle 和 IsCompleted 如何交互?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/406915/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com