Когда все застряло в Blazor WASMC#

Место общения программистов C#
Ответить
Anonymous
 Когда все застряло в Blazor WASM

Сообщение Anonymous »

У меня есть следующий код на странице Blazor. Он вызывает OnParameterSetAsync(). я использовал только асинхронное ожидание. Нет Task.Wait() или Task.Result.

Код: Выделить всё

   private async Task SelectNewAddress(AddressElement elem, bool withFillParam)
{

foreach (var fieldSource in elem.DicFields.Values)
{
if (fieldSource.Id > 0)
address.SelectAddressField(fieldSource);
}

var lowLevelElementKey = address.DicFields.Where(p => p.Value != null && p.Value.Id > 0).Max(p => p.Key);

List listTasks = new List();

if (withFillParam)
{
var t = FillParams();
listTasks.Add(t);
}

foreach (var kkey in address.DicFields.Keys)
{
var field = address.DicFields[kkey];

if (field.Id > 0 && field.IdParent > 0)
{
var t1 = FillDataSourceForElem(field);

listTasks.Add(t1);

if (kkey == lowLevelElementKey)
{
var t2 = Task.Run(async () =>
{
if (field.Level >= 1 && field.Level  { StateHasChanged(); });
//_ = Task.Run(async () =>
// {
//     await Task.WhenAll(listTasks.ToArray());
//     await InvokeAsync(() => { StateHasChanged(); });

// });

}
await Task.WhenAll(listTasks.ToArray()) зависает каждый раз при открытии страницы с этим кодом, но только в первый раз после запуска сервера. Если я закрою страницу браузера и снова открою ее, код не застрянет и будет работать нормально. Тот же код отлично работает в Blazor MAUI. Я подумал, что это мертвая блокировка, затем добавил ConfigurationAwait(false), но это не помогло. Если я запущу и забуду WhenAll, как в комментарии, он тоже будет работать нормально, но мне нужно заблокировать интерфейс до завершения операции. В каждой функции FillDataSourceForElem, FillAllChilds и т. д. просто вызывается _httpClient.GetAsync(). Серверная часть работает нормально и быстро возвращает ответ.
Если я удалю дополнительную задачу и WhenAll и попробую дождаться каждой функции (FillDataSourceForElem, FillAllChilds и т. д.), я застряну в ожидании _httpClient.GetAsync(), но каждый раз я застреваю на разных функциях. Первый раз в FillDataSourceForElem, следующий раз в FillAllChilds и т. д.
Теперь я понятия не имею, почему это происходит.
Похоже на тупую блокировку...
В F12 я вижу, что браузер сделал запрос, но не получил ответа (статус ожидания). Затем WhenAll завис, потому что задачи не могут быть выполнены, но почему это происходит только 1 раз, почему это работает в MAUI и почему GetAsync зависает (если я делаю точку останова на стороне сервера в контроллере, я вижу, что метод контроллера возвращает результат).
Если я запускаю и забываю (как в комментарии), я вижу, что все запросы выполняются быстро, получаю результат от сервера и жду, когда WhenAll() в _ = Task.Run завершится нормально.
если кто-нибудь знает причину, буду признателен.
Я использую httpClient, что инициализировать вот так

Код: Выделить всё

     HttpClient _client;
protected override async System.Threading.Tasks.Task  OnInitializedAsync()
{
_client = ClientFactory.CreateClient("clientName");

}
Изменить:
Полный стек вызовов:
В компоненте blazor

Код: Выделить всё

 protected override async Task OnParametersSetAsync()
{
await Initialise();
}
тогда

Код: Выделить всё

 private async Task Initialise()
{

var result = await GetAddressFromDB();
}
тогда

Код: Выделить всё

private async Task GetAddressFromDB()
{
try
{
var elem = await _client.GetFromJsonAsync($"url?idForm={IdForm}");
if (elem is null)
return false;

if (elem.Region is null)
return false;
if (elem.Region.Id = 1 && elem.Level  p.Level == elem.Level).ToList();

}
else if (elem.Level == 9)
{

fields = await GetSteads(elem.IdParent);

}
else if (elem.Level == 10)
{

var rez = await GetHouses(elem.IdParent);
fields = rez.Select(x => { AddressField b = x; return b; }).ToList();

}
else if (elem.Level == 11)
{

fields = await GetAppartments(elem.IdParent);

}
else if (elem.Level == 12)
{

fields = await GetRooms(elem.IdParent);

}
else if (elem.Level == 17)
{

fields = await GetCarPlaces(elem.IdParent);

}

foreach (var fieldChild in fields)
{
address.AddAddreesFieldInSameLevel(fieldChild);
}

}

private async Task SearchChildsElements(long idParent)
{
List result = null;
try
{
result = await _client.GetFromJsonAsync($"url?id={idParent}&useMun={_isMunHierarchy}");
}
catch (Exception ex)
{

//log here
}
if (result is null)
return new List();

return result;
}
Ответ
Не используйте несколько задач в WASM. После отключения дополнительных задач зависание прекратилось.

Подробнее здесь: https://stackoverflow.com/questions/783 ... lazor-wasm
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»