C# 多个异步数据使用者的事件与RegisterWaitForSingleObject
如果我有多个异步调用者等待数据更新,那么在这个代码段中,我应该在什么时候选择一种方法而不是另一种方法:C# 多个异步数据使用者的事件与RegisterWaitForSingleObject,c#,task-parallel-library,C#,Task Parallel Library,如果我有多个异步调用者等待数据更新,那么在这个代码段中,我应该在什么时候选择一种方法而不是另一种方法: public delegate void NewDataHandler(int data); public class DataSource { public event NewDataHandler OnNewData; public AutoResetEvent are = new AutoResetEvent(false); public void AddD
public delegate void NewDataHandler(int data);
public class DataSource {
public event NewDataHandler OnNewData;
public AutoResetEvent are = new AutoResetEvent(false);
public void AddData(int i) {
OnNewDataInvoke(i);
}
private void OnNewDataInvoke(int data) {
OnNewData?.Invoke(data);
are.Set();
}
public Task WaitEventAsync() {
var tcs = new TaskCompletionSource<bool>();
var subscribtion = (NewDataHandler)null;
subscribtion = (i) => {
tcs.TrySetResult(true); // note that i ignored here, but could send actual data
OnNewData -= subscribtion;
};
OnNewData += subscribtion;
return tcs.Task;
}
public Task WaitAREAsync() {
var tcs = new TaskCompletionSource<bool>();
var rwh = ThreadPool.RegisterWaitForSingleObject(are,
delegate { tcs.TrySetResult(true); }, null, -1, true);
var t = tcs.Task;
t.ContinueWith(_ => rwh.Unregister(null));
return t;
}
}
public委托void NewDataHandler(int-data);
公共类数据源{
公共事件NewDataHandler OnNewData;
public AutoResetEvent are=新的AutoResetEvent(false);
公共无效添加数据(int i){
OnNewDataInvoke(i);
}
私有void OnNewDataInvoke(int数据){
OnNewData?调用(数据);
are.Set();
}
公共任务WaitEventAsync(){
var tcs=new TaskCompletionSource();
var subscribtion=(NewDataHandler)null;
认购=(i)=>{
TrySetResult(true);//注意,我在这里忽略了它,但可以发送实际数据
OnNewData-=订阅;
};
OnNewData+=订阅;
返回tcs.Task;
}
公共任务WaitAREAsync(){
var tcs=new TaskCompletionSource();
var rwh=ThreadPool.RegisterWaitForSingleObject(是,
委托{tcs.TrySetResult(true);},null,-1,true);
var t=tcs.Task;
t、 ContinueWith(=>rwh.Unregister(null));
返回t;
}
}
事件更常见,允许捕获数据有效负载,而不仅仅是数据已更新的信号。RWFSO有什么好处吗
(对于许多订阅者来说,Rx是一个简单的答案,但我正在尝试对基于拉的异步数据流进行建模)
RegisterWaitForSingleObject
与事件结合使用成本更高,也更难使用。我现在无法想象有什么理由使用它
TaskCompletionSource
可以同时作为事件,这是一种很好的模式。显然,此“事件”只能设置一次TaskCompletionSource
与TPL的其余部分(Wait
和任务组合器)配合良好。您可以使用TaskCompletionSource
从等待的结果返回数据作为有效负载。@YuvalItzchakov是的,但只有事件才允许捕获数据。在这种情况下使用RWFSO有什么理由吗?我看不出有什么不同。一个是基于事件的,另一个是基于回调的(几乎相同)。最后,只剩下一个事件或RWFSO+,两者都使用TCS。问题是保留哪一个和删除哪一个:WaitEventAsync
或WaitAREAsync
,它们不在任何组合中使用。这里只是一个如何使用两者的示例。保持WaitEventAsync。我想我已经说得很清楚,等待是没有好处的。显然不是。那么我们可以说RWFSO只有在事件模式不可能时才有用,例如非托管等待句柄吗?这是一个使用它的好地方,因为您必须这样做。当你喜欢简单的时候,你也可以等待事件的发生。这是一个线程。RegisterWaitForSingleObject块1/64线程AFAIK。