Event wrapping with TaskCompletionSource and BufferBlock <T>
This describes the template discussed here by Lucian ( Tip 3: Wrap events in the APIs that return tasks and wait for them ).
I am trying to implement it on a often called method, which looks something like the far-fetched code below:
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;
}
I am concerned about performance when TaskCompletionSourceevery call is updated (let me say that I call this method every 100 ms).
Then I thought about using it BufferBlock<T>, thinking that it would not be updated every call. So it will look like this:
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();
}
Callers would call this as:
for (var i=0; i<10000; i++) {
await BlackBoxAsync().ConfigureAwait(false);
}
Does anyone have any thoughts on using it BufferBlock<T>instead?
+4
1
, , await , , Task , . - TaskCompletionSource.
, IMO BufferBlock (, , TaskCompletionSource ReceiveAsync)
, , , ThreadPool , . Task.Run?
public Task BlackBoxAsync()
{
return Task.Run(() => DoSomethingStuff());
}
+5