- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我通常对部分实现接口(interface)持谨慎态度。但是,IAsyncResult
有点特殊,因为它支持几种完全不同的使用模式。您使用/查看使用 AsyncState
/AsyncCallback
模式的频率,而不是使用 AsyncWaitHandle
调用 EndInvoke
>,或轮询 IsCompleted
(糟糕)?
相关问题:Detecting that a ThreadPool WorkItem has completed/waiting for completion .
考虑这个类(非常近似,需要锁定):
public class Concurrent<T> {
private ManualResetEvent _resetEvent;
private T _result;
public Concurrent(Func<T> f) {
ThreadPool.QueueUserWorkItem(_ => {
_result = f();
IsCompleted = true;
if (_resetEvent != null)
_resetEvent.Set();
});
}
public WaitHandle WaitHandle {
get {
if (_resetEvent == null)
_resetEvent = new ManualResetEvent(IsCompleted);
return _resetEvent;
}
public bool IsCompleted {get; private set;}
...
它有 WaitHandle
(延迟创建,正如 IAsyncResult
文档中所述)和 IsCompleted
,但我没有看到合理的实现对于 AsyncState
({return null;}
?)。那么它实现IAsyncResult
有意义吗?请注意,Parallel Extensions 库中的 Task
确实实现了 IAsyncResult
,但只有 IsCompleted
是隐式实现的。
最佳答案
您似乎有几个问题。让我们单独处理它们
延迟创建 WaitHandle
是的,这是最正确的方法。您应该以线程安全的方式执行此操作,但懒惰是一种方式。
但诀窍在于处理 WaitHandle。 WaitHandle 是 IDisposable 的基础,必须及时处理。 IAsycResult 的文档不包括这种情况。执行此操作的最佳方法是在 EndInvoke 中。 BeginInvoke 的文档明确指出对于每个 BeginInvoke,必须有一个相应的 EndInvoke(或 BeginRead/EndRead)。这是处理 WaitHandle 的最佳位置。
AsyncState应该如何实现?
如果您查看返回 IAsyncResult 的标准 BCL API,其中大多数都采用状态参数。这通常是从 AsyncState 返回的值(有关示例,请参见套接字 API)。对于返回 IAsyncResult 的任何 API BeginInvoke 样式 API,包含一个类型为对象的状态变量是一个很好的做法。没有必要,但很好的做法。
在没有状态变量的情况下,返回null是可以接受的。
IsCompleted API
这将高度依赖于创建 IAsyncResult 的实现。但是,是的,你应该实现它。
关于c# - 显式实现 IAsyncResult,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/405647/
我是一名优秀的程序员,十分优秀!