- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
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 的最佳方式是,如果值为
问题 4
这取决于实现。这里没有办法真正给出一个笼统的答案。
示例
如果您对允许您轻松地在另一个线程上运行委托(delegate)并在完成时访问结果的 API 感兴趣,请查看我的 RantPack Utility Library .它以源代码和二进制形式提供。它有一个完全充实的 Future API,允许并发运行委托(delegate)。
另外还有一个 IAsyncResult 的实现,它涵盖了本文中的大部分问题。
关于c# - 以多线程方式使用 BeginInvoke/EndInvoke。 AsyncCallback、AsyncWaitHandle 和 IsCompleted 如何交互?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/406915/
在异步编程模型中,似乎有 4 种方式(如 Calling Synchronous Methods Asynchronously 中所述)进行异步方法调用。 调用 EndInvoke() 方法使调用线程
1)调用AsyncWaitHandle.WaitOne可能会阻塞客户端还是一定会阻塞客户端? 2)WaitAll,WaitOne,WaitAny 有什么区别? 最佳答案 WaitHandle.Wait
在此先感谢您的帮助。 我想在代码中的某个时候取消AsyncWaitHandle.WaitOne()(这意味着我不想再阻止了),但我只是找不到解决方法。也许,这是我程序的逻辑问题,但是一旦给出退出信号,
代码如下: class LongOp { //The delegate Action longOpDelegate = LongOp.DoLongOp; //The resul
也许这是个愚蠢的问题。 Task 类是这样声明的: public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable IAsyncR
我有个问题,AsyncWaitHandle.WaitOne 会阻塞 CLR 线程吗?还是创建 I/O 完成端口? 例如,当我运行我的应用程序时,我启动了一个初始化一些数据的任务“A”,当新请求到达时,
Andreas Huber 对 this question 的回答给了我一个实现的想法 Concurrent使用异步委托(delegate)而不是线程池。但是,我发现很难理解 AsyncCallbac
我正在通过以下方式连接到我在另一台服务器上创建的服务: using (var clientSocket = new TcpClient()) { ... //Connect async
我是一名优秀的程序员,十分优秀!