Как проверить возможность тупика в коде c # - PullRequest
0 голосов
/ 02 января 2019

Мое приложение иногда останавливается в приведенном ниже коде, не всегда, но иногда.

Все 3 метода CalcQuarterlyFigures, CalcWeeklyFigures & CalcMonthlyFigures return Task<List<MyClass>>.

Обратите внимание, это выполняется внутри цикла foreach.

List<Task> TaskList = new List<Task>();

if(i.DoCalculateAllHistory) {

    var quarterly = CalcQuarterlyFigures(QuarterlyPrices, i.SeriesID);
    TaskList.Add(quarterly);
    var weekly = CalcWeeklyFigures(WeeklyPrices, i.SeriesID);
    TaskList.Add(weekly);
    var monthly = CalcMonthlyFigures(MonthlyPrice, i.SeriesID);
    TaskList.Add(monthly);

    Task.WaitAll(TaskList.ToArray());

    if(monthly.Result.Count > 0)
        monthlyPerfFig.AddRange(monthly.Result);

    if(weekly.Result.Count > 0)
        weeklyPerfFig.AddRange(weekly.Result);

    if(quarterly.Result.Count > 0)
        quartPerfFig.AddRange(quarterly.Result);
} else {

    monthlyPerfFig.AddRange(await CalcMonthlyFigures(MonthlyPrice, i.SeriesID));

}

Я что-то упускаю здесь, что приводит к мертвой блокировке?

1 Ответ

0 голосов
/ 02 января 2019

В предоставленном контексте (пример кода .NET 4.6.1) Task.WaitAll(TaskList.ToArray()) вызовет взаимоблокировку.
Определенно полезный источник: Не блокировать асинхронный код

Вы должны сделать свой блок кода полностью асинхронным

if (i.DoCalculateAllHistory) 
{
    var quarterlyTask = CalcQuarterlyFigures(QuarterlyPrices, i.SeriesID);
    var weeklyTask = CalcWeeklyFigures(WeeklyPrices, i.SeriesID);
    var monthlyTask = CalcMonthlyFigures(MonthlyPrice, i.SeriesID);

    // Task.WhenAll accepts "params" array
    await Task.WhenAll(quarterlyTask, weeklyTask, monthlyTask);

    // You don't need to check for .Count
    // nothing will be added when empty list given to .AddRange  
    quartPerfFig.AddRange(await quarterlyTask);
    weeklyPerfFig.AddRange(await weeklyTask);
    monthlyPerfFig.AddRange(await monthlyTask);
} 
else 
{
    var monthly = await CalcMonthlyFigures(MonthlyPrice, i.SeriesID);
    monthlyPerfFig.AddRange(monthly);
}
...