Tengo una función c # con una firma como: Foo(List<int> data, Action<string> endAction)

No puedo cambiar Foo (es una biblioteca externa).

Soy muy nuevo en c #, principalmente he estado haciendo desarrollo de JS en los últimos años y me pregunto si hay algo similar a lo que se llama 'promisificar' en JS-land. Es decir, hacer que la función que llama a 'Foo' sea asincrónica y esperar a que Foo llame a la devolución de llamada endAction.

3
Seba Kerckhof 15 oct. 2018 a las 23:14

2 respuestas

La mejor respuesta

Puede hacer 'promisificar' a Foo de la siguiente manera:

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;
}

Ahora puedes llamarlo:

string result = await FooAsync(myList);
3
Tom Deseyn 16 oct. 2018 a las 07:14

No hay ningún método integrado similar a promisify en C # /. NET, pero puede usar una instancia de TaskCompletionSource para crear un Task que se puede completar cuando se llama a la devolución de llamada. .

TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
Foo(list, (string callbackData) => { tcs.SetResult(callbackData); });
string result = await tcs.Task;
2
Shant Marouti 15 oct. 2018 a las 22:59