Как «ждать» событие «ждать».
-
27-10-2019 - |
Вопрос
В настоящее время у меня есть этот код:
TaskCompletionSource<String> tcs = new TaskCompletionSource<String>();
// ...
process.OutputDataReceived += (sender, e) =>
{
if (e.Data == null)
{
outputWaitHandle.Set();
}
else
{
tcs.SetResult(e.Data.ToString());
}
};
// ...
return tcs.Task;
Тогда пользователь этой функции работает как:
private async void Foo_Click(object sender, RoutedEventArgs e)
{
String output = await ExecuteCommand();
}
Теперь проблема в том, что я получаю эту ошибку:
Первое шанс исключение типа 'System.InvalidoPerationException' произошло в mScorlib.dll невозможное исключение типа 'System.invalidoperationException' произошло в mscorlib.dll
Дополнительная информация: была предпринята попытка перевести задачу в окончательное состояние, когда оно уже завершено
Эта проблема бросается, когда я использую tcs.SetResult()
.
Решение
Событие с выводами, заведенное в каждой строке, записанной в Stdout (а затем в последний раз с данными == nul Анкет
Предполагая, что вы хотите сохранить ту же структуру для Кодекса, ваш пункт другой пункт должен измениться от tcs.setresult (e.data.tostring ()); Для хранения линии в E.Data в StringBuffer, List или что -то еще (она не включает в себя Newline, поэтому, если вы хотите сохранить это, вам нужно добавить его обратно).
Тогда ваш пункт «если» сделает tcs.setresult (stringbuffer.toString ()); (Или как бы вы решили сохранить линии) перед тем, как сделать outputwaithandle.set ()
Убедитесь, что у вас есть перенаправление StandardOutput = true и redirectStandarderRor = false, поскольку в противном случае процесс может блокировать, если он записывает достаточно Stderr, и вы попросили его перенаправить, но не прочитали его. Для получения подробной информации об этом ищите «тупик» в DOC @ http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standarderror.aspx
Другие советы
Вы обертываете асинхронный рисунок на основе событий (EAP).
Попробуйте эту статью MSDN: TPL и традиционное асинхронное программирование .NET
Как только у вас есть Task<T>
, Вы можете await
Это.