Ответ 1
Ваша проблема в том, что вы блокируете поток пользовательского интерфейса при вызове .Result
, и вы сказали продолжение после Task.Delay
для запуска в потоке пользовательского интерфейса. Таким образом, вы блокируете пользовательский интерфейс, ожидая задачи, которая заблокирована при ожидании, когда пользовательский интерфейс станет бесплатным, классический тупик.
Два решения. Сначала сделайте кнопку click async тоже.
private async void buttonOk_Click(object sender, System.EventArgs e)
{
var asyncResolvedIssue = api.ResolveIssue(issue, revision, pathList);
if (await asyncResolvedIssue) {} // <== no deadlock!
}
Обработчики событий - это единственное место, где вам разрешено делать async void
.
Другой вариант: Task.Delay
не нужно, чтобы остальная часть его функции выполнялась в потоке пользовательского интерфейса, установив ConfigureAwait(bool)
значение false.
public async Task<bool> ResolveIssue(Issue issue, int revision, string[] pathList)
{
await Task.Delay(1000).ConfigureAwait(false);
return true;
}
Теперь строка кода после Task.Delay
будет запускаться в потоке threadpool вместо потока пользовательского интерфейса и не будет блокироваться тем фактом, что поток пользовательского интерфейса в настоящее время заблокирован.