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

All Articles