C# 使用TaskCompletionSource与BufferBlock包装事件<;T>;

C# 使用TaskCompletionSource与BufferBlock包装事件<;T>;,c#,async-await,task-parallel-library,tpl-dataflow,taskcompletionsource,C#,Async Await,Task Parallel Library,Tpl Dataflow,Taskcompletionsource,Lucian在这里讨论了一种模式() 我试图在一个经常调用的方法上实现它,该方法类似于下面的人工代码: public Task BlackBoxAsync() { var tcs = new TaskCompletionSource<Object>(); // new'ed up every call ThreadPool.QueueUserWorkItem(_ => { try {

Lucian在这里讨论了一种模式()

我试图在一个经常调用的方法上实现它,该方法类似于下面的人工代码:

public Task BlackBoxAsync() 
{ 
    var tcs = new TaskCompletionSource<Object>();  // new'ed up every call
    ThreadPool.QueueUserWorkItem(_ => 
    { 
        try 
        { 
            DoSomethingStuff(); 
            tcs.SetResult(null); 
        } 
        catch(Exception exc) { tcs.SetException(exc); } 
    }); 
    return tcs.Task; 
}
调用对象会像这样调用它:

for (var i=0; i<10000; i++) {
 await BlackBoxAsync().ConfigureAwait(false);
}

for(var i=0;i无论采用何种解决方案,如果每次调用此方法时都想等待一个任务,那么创建一个新的
任务是不可避免的,因为任务是不可重用的。最简单的方法是使用
TaskCompletionSource

因此,第一个选项比使用
BufferBlock
更可取(毫不奇怪,)


更重要的是,您的代码似乎只是将工作卸载到
线程池
,并返回表示该工作的任务。为什么不使用简单的
任务。运行

public Task BlackBoxAsync() 
{
    return Task.Run(() => DoSomethingStuff());
}

你知道反应式扩展吗?这是“新的”并且比TAP好吗?它比TAP旧,但在4.5版本问世时。它是一个框架,而不是一个单独的系统(有点像实体框架vs
SqlCommand
)。谢谢你的输入。这个方法是人为的,只是为了说明这个场景。我真正的用途实际上是一个由TaskCompletionSource包装的事件。@AlpineScramber得到了它。所以忽略第二部分。
public Task BlackBoxAsync() 
{
    return Task.Run(() => DoSomethingStuff());
}