Когда Task.IsCancelled установлен как true?

Когда придет Task.IsCanceled = true;

Код:

            var cts = new CancellationTokenSource();
            string result = "";
            cts.CancelAfter(10000);
            try
            {
                Task t = Task.Run(() =>
                {
                    using (var stream = new WebClient().OpenRead("http://www.rediffmail.com"))
                    {
                        result = "success!";
                    }
                    cts.Token.ThrowIfCancellationRequested();
                }, cts.Token);

                Stopwatch timer = new Stopwatch();
                timer.Start();
                while (timer.IsRunning)
                {
                    if (timer.ElapsedMilliseconds <= 10000)
                    {
                        if (result != ""){                                                                                      
                            timer.Stop();
                           Console.WriteLine(result);
                     }
                    }
                    else
                    {
                        timer.Stop();
                        //cts.Cancel();
                        //cts.Token.ThrowIfCancellationRequested();
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine(t.IsCanceled); // still its appear in false.
            }

Мое требование - Задание не выполнено до 10 секунд, Необходимо отменить задание.

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

2 ответа

Вы должны передать токен вашему методу. Следует проверить токен и уважать призыв к Cancel() из CancellationTokenSource,

Или ты делаешь это сам

Task t = Task.Factory.StartNew(() =>
{
    myResult = method();  // Request processing in parallel

    cts.Token.ThrowIfCancellationRequested(); // React on cancellation 
}, cts.Token);

Полный пример таков:

async Task Main()
{
    var cts = new CancellationTokenSource();
    var ct = cts.Token;
    cts.CancelAfter(500);

    Task t = null;
    try
    {
        t = Task.Run(() => { Thread.Sleep(1000); ct.ThrowIfCancellationRequested(); }, ct);
        await t;
        Console.WriteLine(t.IsCanceled);
    }
    catch (OperationCanceledException)
    {
        Console.WriteLine(t.IsCanceled);
    }
}

Выход заключается в том, что OperationCanceledException брошен и результат

Правда

если вы удалите ct.ThrowIfCancellationRequested(); часть это покажет

Ложь

Редактировать:

Теперь вы обновили вопрос, некоторые комментарии по этому поводу. Во-первых, вам больше не понадобится таймер, так как вы используете CancelAfter метод. Во-вторых, вам нужно await твое задание. Так что получается примерно так:

string result = "";
cts.CancelAfter(10000);
Task t = null;
try
{
    t = Task.Run(() =>
    {
        using (var stream = new WebClient().OpenRead("http://www.rediffmail.com"))
        {
            cts.Token.ThrowIfCancellationRequested();
            result = "success!";
        }
    }, cts.Token);

    await t;
}
catch (OperationCanceledException)
{
    Console.WriteLine(t.IsCanceled); 
}

Это должно показать, что t.IsCanceled является true но, конечно, только когда вызов WebClient занимает больше 10 секунд.

Из документации:

Задача будет выполнена в состоянии TaskStatus.Canceled при любом из следующих условий:

  1. Его CancellationToken был помечен для отмены до начала выполнения задачи.

  2. Задача подтвердила запрос на отмену в уже сигнализированном CancellationToken, выдав исключение OperationCanceledException, содержащее тот же CancellationToken.

  3. Задача подтвердила запрос отмены в уже сигнализированном CancellationToken, вызвав метод ThrowIfCancellationRequested в CancellationToken.

Так что в основном вам нужно будет бросить OperationCanceledException в вашей задаче, чтобы заставить государство, например, выполнив cts.Token.ThrowIfCancellationRequested() только после того, как вы отмените это.

Но намерение этого механизма несколько наоборот. Вы отменяете источник, скажем, пока пользователь нажимает кнопку "Отмена" в вашей форме (вне вашей задачи), задача просто проверяет, была ли запрошена отмена в некотором сохранении, чтобы отменить пункты ее кода.

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