简体   繁体   中英

Promisify / async-await callback in c#

I have ac# function with a signature like: Foo(List<int> data, Action<string> endAction)

I can't change Foo (it's an external library).

I'm very new to c#, I've mainly been doing JS development in recent years and I wonder if there's something similar to what is called 'promisify' in JS-land. That is, to make the function calling 'Foo' async and await for Foo to call the endAction callback.

You can make 'promisify' Foo as follows:

static Task<string> FooAsync(List<int> data)
{
    var tcs = new TaskCompletionSource<string>();
    Action action = () => Foo(data, result => tcs.SetResult(result));
    // If Foo isn't blocking, we can execute it in the ThreadPool:
    Task.Run(action);
    // If it is blocking for some time, it is better to create a dedicated thread
    // and avoid starving the ThreadPool. Instead of 'Task.Run' use:
    // Task.Factory.StartNew(action, TaskCreationOptions.LongRunning);
    return tcs.Task;
}

Now you can call it:

string result = await FooAsync(myList);

There isn't any built-in method similar to promisify in C#/.NET but you can use an instance of TaskCompletionSource to create a Task that can be completed when the callback is called.

TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
Foo(list, (string callbackData) => { tcs.SetResult(callbackData); });
string result = await tcs.Task;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM