Task.WaitAll() никогда не завершается

Думаю, я немного неправильно понял.

Я инициализирую два элемента управления DxRichText и думаю, что у меня что-то не так в настройке. Но я не вижу чего. Я пытаюсь, чтобы эта загрузка происходила параллельно с другой инициализацией.

У меня есть следующие методы:

      private Task InitializeRichText(DxRichEdit editor, Organization? org,
    RichText? src, RichTextModel model)
{

    if (org == null || src == null)
        return editor.NewDocumentAsync().AsTask();

    model.RichText = src;
    model.BlobUrl = BlobService.GetBlobUrl(src.OpenXmlFilename);
    return LoadUrlAsync(editor, model.BlobUrl);
}

private async Task LoadUrlAsync(DxRichEdit editor, string url)
{
    using (var httpClient = new HttpClient())
    {
        using (var response = await httpClient.GetAsync(url))
        {
            if (response.IsSuccessStatusCode)
            {
                await using (var stream = await response.Content.ReadAsStreamAsync())
                {
                    await editor.LoadDocumentAsync(stream, DocumentFormat.OpenXml);
                }
            }
        }
    }
}

Важный предмет:NewDocumentAsync()иLoadDocumentAsync()вернутьValueTask(не задача).

В моемOnInitializedAsync()У меня есть следующее (с большим количеством другого кода между ними):

      var listRichTasks = new List<Task>();

await Task.Yield();
listRichTasks.Add(InitializeRichText(RichEditDesc, _organization,
                        _organization?.Description, Model.Description));
listRichTasks.Add(InitializeRichText(RichEditNews, _organization,
                        _organization?.News, Model.News));

// this call is never returning
Task.WaitAll(listRichTasks.ToArray());

Что у меня не так?

1 ответ

Согласно документации Microsoft (спасибо user7484766), вам не следует вызывать методы блокировки в компонентах. Одним из особо упомянутых является .

Насколько я понимаю, такие вызовы могут по существу привести к тупику, когда вы ожидаете (блокируете) завершения задачи, а задача ждет, пока контекст, который вы сейчас блокируете, освободится, чтобы он мог вернуть свои результаты. . По сути, они ждут друг друга вечно.

Есть еще один метод,, который представляет собой асинхронный метод, который примерно делает то же самое (он также возвращает результаты), а не метод синхронизации, такой как.

Таким образом, мы можем изменить ваш код на это:

      var listRichTasks = new List<Task>();

await Task.Yield();
listRichTasks.Add(InitializeRichText(RichEditDesc, _organization,
                        _organization?.Description, Model.Description));
listRichTasks.Add(InitializeRichText(RichEditNews, _organization,
                        _organization?.News, Model.News));

// this call is never returning
await Task.WhenAll(listRichTasks.ToArray());

И это должно помочь вам выйти из тупика, в котором вы, кажется, находитесь.

Для получения дополнительной информации об асинхронности я рекомендую блог Стивена Клири. В комментариях была предоставлена ​​соответствующая статья: Don't Block on Async Code .

Другие вопросы по тегам