Task.Run () & Task.Delay () прервано через некоторое время - PullRequest
1 голос
/ 17 апреля 2019

Я создал службу Windows в C #, и в этой службе я создал 4 потока и запускаю их в фоновом режиме каждые 10 секунд.

Ниже приведен код:

var ThreadSize = 4;    
for (int i = 0; i < ThreadSize; i++)
{
    Task.Run(async () =>
    {
        while (1 == 1)
        {
            try
            {
                //Logic
                await Task.Delay(10000, cancelSource.Token);
            }
            catch (Exception ex)
            {
                //Log the exception
            }
        }
    });
}

Цикл for будет выполнен только один раз и создаст 4 потока. Я использую Task.Delay для ожидания потока в течение 10 секунд, а затем снова выполняю мою логику. Он будет выполнять мою логику каждые 10 секунд.

Код работает нормально, но через некоторое время все мои потоки завершаются (не работает). Я имею в виду, что код в логике не работает после пары часов. Там нет исключений на всех. Может кто-нибудь предположил, что пошло не так. Заранее спасибо.

Отредактированный код:

CancellationTokenSource cancelSource;

protected override void OnStart(string[] args)
{
    cancelSource = new CancellationTokenSource();
    Process.StartProcess(cancelSource);
}

protected override void OnStop()
{
    cancelSource.Cancel();
}


public static void StartProcess(CancellationTokenSource cancelSource)
{
    var ThreadSize = 4;
    for (int i = 0; i < ThreadSize; i++)
    {
        Task.Run(async () =>
        {
            while (1 == 1)
            {
                try
                {
                    //Logic
                    await Task.Delay(10000, cancelSource.Token);
                }
                catch (Exception ex)
                {
                    //Log the exception
                }
            }
        });
    }
}

Ответы [ 2 ]

4 голосов
/ 17 апреля 2019

Если какое-либо исключение возникает в пределах Task.Run, оно будет сохранено и выброшено, когда задача ожидается.Вы не ожидаете выполнения задачи, поэтому все возникшие исключения не будут видны.

Вам следует дождаться Task.Run, указав ключевое слово await или позвонив по нему .Wait().

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

Прочтите эту статью для получения дополнительной информации

1 голос
/ 17 апреля 2019

Ваша главная проблема в

catch (Exception ex)
{
    throw;
}

Это фактически означает, что вы не ловите никаких ошибок. С тем же эффектом или отсутствием эффекта вы могли бы убрать попытку / улов.

Основная структура вашей службы выглядит нормально, она не остановится сама по себе. Выбор Task vs Thread не так важен.

Ваша ошибка происходит внутри //Logic и не обрабатывается.

Вам понадобится некоторая форма регистрации, чтобы выяснить это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...