C# 使用TaskCompletionSource与BufferBlock包装事件<;T>;
Lucian在这里讨论了一种模式() 我试图在一个经常调用的方法上实现它,该方法类似于下面的人工代码: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 {
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版本问世时。它是一个框架,而不是一个单独的系统(有点像实体框架vsSqlCommand
)。谢谢你的输入。这个方法是人为的,只是为了说明这个场景。我真正的用途实际上是一个由TaskCompletionSource包装的事件。@AlpineScramber得到了它。所以忽略第二部分。
public Task BlackBoxAsync()
{
return Task.Run(() => DoSomethingStuff());
}