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。