【发布时间】:2015-08-22 01:07:03
【问题描述】:
Lucian 在这里讨论了一个模式 (Tip 3: Wrap events up in Task-returning APIs and await them)。
我正在尝试在一个经常调用的方法上实现它,该方法看起来像下面的人为代码:
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;
}
我担心性能,因为每次调用都会更新TaskCompletionSource(假设我每 100 毫秒调用一次此方法)。
我当时正在考虑改用BufferBlock<T>,认为它不会在每次调用时都更新。所以它看起来像:
private readonly BufferBlock<object> signalDone; // dummy class-level variable, new'ed up once in CTOR
public Task BlackBoxAsync()
{
ThreadPool.QueueUserWorkItem(_ =>
{
try
{
DoSomethingStuff();
signalDone.Post(null);
}
catch(Exception exc) { }
});
return signalDone.ReceiveAsync();
}
调用对象会这样称呼它:
for (var i=0; i<10000; i++) {
await BlackBoxAsync().ConfigureAwait(false);
}
有人对改用BufferBlock<T> 有任何想法吗?
【问题讨论】:
-
你知道响应式扩展吗?
-
这是“新”并且比 TAP 更好吗?
-
Rx 比 TAP 早,但 it was updated to use TAP 在 4.5 发布时。它是一个框架,而不是一个单独的系统(有点像 Entity Framework vs
SqlCommand)。
标签: c# async-await task-parallel-library tpl-dataflow taskcompletionsource