У меня появились ОГРОМНЫЕ сомнения относительно моего кода, и мне нужны советы от более опытных программистов.
В моем приложении при нажатии кнопки приложение запускает команду, которая вызывает метод ScrapJockeys
:
if (UpdateJockeysPl) await ScrapJockeys(JPlFrom, JPlTo + 1, "jockeysPl"); //1 - 1049
ScrapJockeys
запускает цикл for
, повторяя кодовый блок от 20 до 150 тысяч раз (зависит от случая).Внутри цикла мне нужно вызвать метод службы, где выполнение метода занимает много времени.Кроме того, я хотел иметь возможность отмены цикла и всего, что происходит внутри цикла / метода.
Сейчас я нахожусь с методом со списком задач и внутри цикласрабатывает Task.Run
.Внутри каждой задачи я вызываю ожидаемый сервисный метод, который сокращает время выполнения всего до 1/4 по сравнению с синхронным кодом.Кроме того, каждой задаче назначен токен отмены, как в примере ссылка GitHub :
public async Task ScrapJockeys(int startIndex, int stopIndex, string dataType)
{
//init values and controls in here
List<Task> tasks = new List<Task>();
for (int i = startIndex; i < stopIndex; i++)
{
int j = i;
Task task = Task.Run(async () =>
{
LoadedJockey jockey = new LoadedJockey();
CancellationToken.ThrowIfCancellationRequested();
if (dataType == "jockeysPl") jockey = await _scrapServices.ScrapSingleJockeyPlAsync(j);
if (dataType == "jockeysCz") jockey = await _scrapServices.ScrapSingleJockeyCzAsync(j);
//doing some stuff with results in here
}, TokenSource.Token);
tasks.Add(task);
}
try
{
await Task.WhenAll(tasks);
}
catch (OperationCanceledException)
{
//
}
finally
{
await _dataServices.SaveAllJockeysAsync(Jockeys.ToList()); //saves everything to JSON file
//soing some stuff with UI props in here
}
}
Так что по моему вопросу все в порядке с моим кодом?Согласно этой статье :
Многие асинхронные новички начинают с попыток рассматривать асинхронные задачи так же, как параллельные (TPL) задачи, и это серьезная ошибка.
Что мне тогда использовать?
И согласно этой статье :
На загруженном сервере такая реализация может убить масштабируемость.
Итак, как мне это сделать?
Обратите внимание, что сигнатура метода интерфейса службы Task<LoadedJockey> ScrapSingleJockeyPlAsync(int index);
И я тоже неНа 100% уверен, что я правильно использую Task.Run
в своем классе обслуживания.Методы внутри обертывают код внутри await Task.Run(() =>
, как в примере ссылка на GitHub :
public async Task<LoadedJockey> ScrapSingleJockeyPlAsync(int index)
{
LoadedJockey jockey = new LoadedJockey();
await Task.Run(() =>
{
//do some time consuming things
});
return jockey;
}
Насколько я понимаю из статей, это своего рода анти-шаблон.Но я немного смущен.Исходя из этого ТАКОГО ответа , все должно быть в порядке ...?Если нет, то как его заменить?