|
9
|
| Zephyr was a Friend of Mine · 技术社区 · 15 年前 |
|
|
1
10
异步操作完成时,会发出ASyncWaitHandle.WaitOne()信号。同时调用CallBack()。 这意味着WaitOne()之后的代码在主线程中运行,回调在另一个线程中运行(可能与运行DoLongOp()的代码相同)。这将导致一个竞争条件,其中longOpResult的值在返回时本质上是未知的。
您需要另一个ManualResetEvent,使主线程等待回调设置longOpResult。 |
|
2
5
正如其他人所说,
|
|
|
3
3
发生了什么事
自从你手术后
AsyncWaitHandle.WaitOne() 只等待异步操作完成,而不是回调 BeginInvoke的回调参数实际上是 AsyncCallback delegate ,这意味着您的回调是异步调用的。这是设计的,因为目的是异步处理操作结果(这是回调参数的全部目的)。 由于BeginInvoke函数实际上调用回调函数,因此IAsyncResult.WaitOne调用仅用于操作,不影响回调。 Microsoft documentation (剖面图 异步调用完成时执行回调方法 ). 还有一个很好的解释和例子。 解决方案 如果要同时等待操作和回调,则需要自己处理信令。一个 ManualReset 是一种能给你最大控制权的方法(这就是微软在他们的文档中是如何做到的)。
对于您给出的示例,最好不要使用回调,而是在CallLongOp函数中处理结果,在这种情况下,操作委托上的WaitOne可以正常工作。 |
|
|
5
0
我最近也遇到了同样的问题,我想出了另一个办法来解决它,在我的情况下是有效的。如果超时不在您身边,请在等待句柄为timeout时重新检查标志IsCompleted。在我的例子中,等待句柄在阻塞线程之前和if条件之后发出信号,所以在超时之后重新检查它就可以了。
|
|
|
A B · C#Excel自动调整列避免长文本时出错 1 年前 |
|
|
Megrez7 · C#ToArray转换合并为一行,导致数组元素更改 1 年前 |
|
Aycon · 在工厂方法中释放部分创建的对象的正确方法是什么? 1 年前 |
|
|
Sei · Avalonia/WPF将路由器传递到控制模板 1 年前 |