Wait () вызывает зависание потока пользовательского интерфейса - когда следует использовать Wait ()?
У меня есть следующий код, который подключается к узлу SignalR
private static async Task StartListening()
{
try
{
var hubConnection = new HubConnection("http://localhost:8080/");
IHubProxy hubProxy = hubConnection.CreateHubProxy("Broadcaster");
hubProxy.On<EventData>("notifyCardAccessEvent", eventData =>
{
Log.Info(string.Format("Incoming data: {0} {1}", eventData.Id, eventData.DateTime));
});
ServicePointManager.DefaultConnectionLimit = 10;
await hubConnection.Start();
Log.Info("Connected");
}
catch (Exception ex)
{
Log.Error(ex);
}
}
В моем методе Form_Load
у меня есть этот
StartListening();
Однако Resharper предлагает мне "рассмотреть возможность применения оператора 'await' к результату вызова "
Так я и сделал:
Log.Info("Connecting to SignalR hub...");
StartListening().Wait();
Log.Info("Connected!");
Однако это приводит к зависанию потока пользовательского интерфейса и Connected!
никогда не печатается в файл журнала.
Wait()
? Каковы примеры и сценарии, которые я должен использовать Wait (), и когда следует Я не использую Wait()
?3 ответа:
await
не являетсяWait
. Неясно, что это за код, который вызываетStartListening()
, но один из вариантов-этоawait
, как было предложено:await StartListening();
Однако, в некоторых других случаях это может быть лучше вообще ничего не делать:
StartListening(); // drop the Task on the floor
Или, возможно, использовать
ContinueWith
для ручного продолжения. Поскольку методStartListening
ловит любые исключения, нет ничего плохого в том, чтобы просто игнорировать возвращенныйTask
- так что у вас уже было. Хотя я бы предложил назвать егоStartListeningAsync
.Причина возникновения взаимоблокировка заключается в том, что если вы используете
Wait
, ваш поток пользовательского интерфейса блокирует ожидание завершения асинхронного метода, но этот асинхронный метод захватывает контекст синхронизации, что означает, что для обработки каждого продолжения он пытается попасть в поток пользовательского интерфейса, который блокируется... на нем .
@MarcGravell имеет правильный ответ; я просто отвечу на этот другой вопрос:
Путаница возникает из-за того, что типИтак, мой вопрос заключается в том, когда я должен использовать Wait()? Каковы примеры и сценарии, которые я должен использовать Wait (), и когда я не должен использовать Wait()?
Task
используется для двух почти совершенно разных вещей.
Task
первоначально был представлен в .NET 4.0 как часть параллельной библиотеки задач. Обычно, ты будет использовать параллельный LINQ или классParallel
для параллельной обработки (который использовал типTask
внизу). Однако в расширенных сценариях можно использовать типTask
непосредственно.Task.Wait
использовался для ожидания завершения этих независимых задач.Когда
async
/await
были введены в .NET 4.5, существующий типTask
был почти достаточно хорош, чтобы использоваться в качестве абстрактного "будущего". Поэтому вместо того, чтобы изобретать какой-то новый тип" будущего", они просто немного расширилиTask
, чтобы работать как будущее.Это приводит нас к сегодняшнему дню, где
Task
может использоваться как:
- элемент работы в параллельном вычислении.
- асинхронное будущее.
(есть крошечный кроссворд: вы можете рассматривать параллельную работу как асинхронную, и в редких ситуациях, таких как консольные методы
Main
, Вам нужно блокировать асинхронные задачи; но на данный момент игнорируйте их.)Это означает, что API для
Task
разбивается по этим линиям. Члены такие какStart
,Wait
,Result
, иContinueWith
довольно прочно принадлежат параллельной стороне. В асинхронном миреawait
более уместно.У меня есть маленький столик в нижней части моего
async
введение , которое имеет некоторые новые (асинхронные) эквиваленты для старых (параллельных) способов выполнения вещей.
Вы, кажется, неправильно поняли сообщение от Решарпера. Вместо применения оператора
await
вы вызвали методTask.Wait()
. Они могут казаться похожими, но работают совершенно по-разному.Этот приятный ответ даст больше информации о различиях: https://stackoverflow.com/a/13140963/3465395