Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Action<T> callback to an await

I have a method that takes a Action<String>. When the method finishes its processing it calls the Action<String> with the return value.

MethodWithCallback((finalResponse)=> {
   Console.WriteLine(finalResponse);
});

I want to use this in a web.api async controller. How do I wrap this method so I can await for this method to complete in an async manner. I cannot modify the method itself, it is in a legacy code base.

What I would like to be able to do is this

String returnValue = await MyWrapperMethodThatCallsMethodWithCallback();
like image 202
Aran Mulholland Avatar asked May 30 '13 07:05

Aran Mulholland


People also ask

Can you await a callback?

The await keyword is used in an async function to ensure that all promises returned in the async function are synchronized, ie. they wait for each other. Await eliminates the use of callbacks in . then() and .

Why is async await better than callbacks?

Async functions not only allow the programmer to escape from callback hell and promise chaining in asynchronous code, but they also make the code seemingly synchronous.

Is await in C# blocking?

The await keyword, by contrast, is non-blocking, which means the current thread is free to do other things during the wait.


1 Answers

You can leverage the TaskCompletionSource class and solve the problem in a generic way:

Task<T> AsAsync<T>(Action<Action<T>> target) {
    var tcs = new TaskCompletionSource<T>();
    try {
        target(t => tcs.SetResult(t));
    } catch (Exception ex) {
        tcs.SetException(ex);
    }
    return tcs.Task;
}

That way you don't have to modify your MethodWhitCallback:

var result = await AsAsync<string>(MethodWithCallback);
Console.WriteLine(result);
like image 123
m0sa Avatar answered Nov 14 '22 22:11

m0sa