#c_sharp #async #lambda #task
Каким образом в c# можно сделать async получив значение во внешний метод из лямбды? Вот тестовый пример (он нерабочий): public async TaskTest(MyClass data) { return Task.Run (() => { MyOtherClass result = null; bool endFlag = false; protocol.Invoke((MyOtherClass response) => // это async { endFlag = true; result = response; }, "uri/to/my/rpc", data); for (;;) // а это уже await { Thread.Sleep(200); if (endFlag) break; } return result; }); } Задача функции Test - вытащить значение response из лямбды, и вернуть его, причём, сделать это надо асинхронно, к циклу for(;;) хотелось бы перйти только когда потребуется await. Подскажите, что нужно сделать, и почему этот код студия ругает?
Ответы
Ответ 1
Вероятно, вам надо что то вроде public TaskTest(MyClass data) { return Task.Run (async () => { MyOtherClass result = null; bool endFlag = false; protocol.Invoke((MyOtherClass response) => // это async { endFlag = true; result = response; }, "uri/to/my/rpc", data); for (; ; ) // а это уже await { await Task.Delay(200); if (endFlag) break; } return result; }); } Но если вызов protocol.Invoke не блокирующий, то внутренний таск нам не нужен, у нас же уже асинхронный код. public async Task Test(MyClass data) { MyOtherClass result = null; bool endFlag = false; protocol.Invoke((MyOtherClass response) => // это async { result = response; endFlag = true; // И лучше бы флагать о конце операции в конце метода, чтобы не возникло проблем с race condition }, "uri/to/my/rpc", data); for (; ; ) // а это уже await { await Task.Delay(200); if (endFlag) break; } return result; } а вот уже совсем короткий вариант, что делает по сути то же самое public Task Test(MyClass data) { var tcs = new TaskCompletionSource (); protocol.Invoke((MyOtherClass response) => // это async { tcs.SetResult(response); }, "uri/to/my/rpc", data); return tcs.Task; }
Комментариев нет:
Отправить комментарий