Каждый метод асинхронной имеет свой контекст.
При запуске задачи он может запускаться в новом SynchronizationContext
. «Возможно», потому что если задача уже завершена, например, Task.FromResult(0)
, тогда никакой другой SynchronizationContext
не будет создан и будет использоваться исходный.
Ожидание задания означает, что когда задача будет завершена, следующий оператор будет запущен в исходном SynchronizationContext.
Это поведение можно изменить с помощью Task.ConfigureAwait(continueOnCapturedContext: false)
. Это означает, что следующий оператор будет продолжен в том же контексте. Но это ничего не изменит, сделав Task.FromResult(0).ConfigureAwait(false)
, потому что задача уже завершена, и исходный контекст будет использоваться.
Поэтому ваш Remote.Login("user","password");
будет запущен в исходном контексте, тем самым блокируя поток пользовательского интерфейса, который работает в одном контексте.
Если бы что-то вроде:
public async void LoginButtonClicked()
{
await Task.Delay(5000).ConfigureAwait(false);
Remote.Login("user","password");
}
Тогда Remote.Login("user","password");
выполнить бы в таким образом контекст пул потоков будучи на другом контексте, чем исходный контекст пользовательского интерфейса.
Таким образом, лучший способ исправить ваш код - создать Remote.LoginAsync()
, как указано в ответе @Nicholas W.
Примечания о производительности:, если у вас есть метод асинхронного с несколькими ждут заявления, и вам не нужны некоторые из этих ожидающих, чтобы сделать работу на UI или веб-приложении потоке, то вы можете использовать Task.ConfigureAwait(false)
для того, чтобы предотвратить несколько переключений в контекст пользовательского интерфейса/веб-приложения, который сокращает время выполнения.
'await' только делает что-то фантастическое, если дело не направо. 'Task.FromResult' всегда возвращает завершенную задачу, и поэтому метод продолжает весело проезжать мимо этой точки' await'. –
И этот старый Эрик Липперт [сообщение в блоге] (http://blogs.msdn.com/b/ericlippert/archive/2010/10/29/asynchronous-programming-in-c-5-0-part-two-whence -await.aspx) может помочь: «Весь смысл асинхронных методов заключается в том, чтобы вы оставались в текущем потоке как можно больше». –