Как лучше игнорить TaskCanceledException
От: Shmj Ниоткуда  
Дата: 16.03.20 08:39
Оценка:
Если TaskCanceledException — штатная ситуация и нет смысла ее специально как-то обрабатывать. Не хочется ее отлавливать и писать пустой блок catch в нескольких местах.

Если написать так:

var task = Task.Run(() => { Console.WriteLine(1); })
                .ContinueWith(t => { }, TaskContinuationOptions.OnlyOnCanceled);


— то при отмене задачи — все ОК. А вот если задача не была отменена — то уже сам ContinueWith вызывает TaskCanceledException, ибо так тупо сделали — раз ContinueWith не была исполнена — значит задачу пришлось отменить а значит опять таки злополучный TaskCanceledException.

Как лучше игнорить?
Отредактировано 16.03.2020 8:42 Shmj . Предыдущая версия .
Re: Как лучше игнорить TaskCanceledException
От: Sharov Россия  
Дата: 16.03.20 11:05
Оценка:
Здравствуйте, Shmj, Вы писали:

S> А вот если задача не была отменена — то уже сам ContinueWith вызывает TaskCanceledException, ибо так тупо сделали — раз ContinueWith не была исполнена — значит задачу пришлось отменить а значит опять таки злополучный TaskCanceledException.


Это откуда следует?
Кодом людям нужно помогать!
Re[2]: Как лучше игнорить TaskCanceledException
От: Shmj Ниоткуда  
Дата: 16.03.20 12:17
Оценка: 4 (1)
Здравствуйте, Sharov, Вы писали:

S>Это откуда следует?


Запустите код и убедитесь, что он падает с TaskCanceledException https://dotnetfiddle.net/dGQ7c0 (причем, зависит от компиллера — мне нужон .Net Core).

using System;
using System.Threading.Tasks;
                    
public class Program
{
    public async static Task Main()
    {
        var task = Task.Run(() => { Console.WriteLine(1); })
                .ContinueWith(t => { }, TaskContinuationOptions.OnlyOnCanceled);
        
        await task;

    }
}


Возможно даже это баг компиллера, т.к. Roslyn и .Net-классик — работают иначе.
Отредактировано 16.03.2020 12:18 Shmj . Предыдущая версия .
Re[3]: Как лучше игнорить TaskCanceledException
От: Sharov Россия  
Дата: 16.03.20 12:28
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Возможно даже это баг компиллера, т.к. Roslyn и .Net-классик — работают иначе.


М-да, с одной стороны логично, мы ожидаем задачу, которая была отменена. С другой стороны ее реальный статус WaitingForActivation, т.е. она даже не запускалась...
Интересный момент...
Кодом людям нужно помогать!
Re[4]: Как лучше игнорить TaskCanceledException
От: Shmj Ниоткуда  
Дата: 16.03.20 12:37
Оценка:
Здравствуйте, Sharov, Вы писали:

S>М-да, с одной стороны логично, мы ожидаем задачу, которая была отменена. С другой стороны ее реальный статус WaitingForActivation, т.е. она даже не запускалась...

S>Интересный момент...

Но что же делать? Решение то нужно уже сегодня написать...
Re[5]: Как лучше игнорить TaskCanceledException
От: Sharov Россия  
Дата: 16.03.20 12:53
Оценка:
Здравствуйте, Shmj, Вы писали:

S>>М-да, с одной стороны логично, мы ожидаем задачу, которая была отменена. С другой стороны ее реальный статус WaitingForActivation, т.е. она даже не запускалась...

S>>Интересный момент...

S>Но что же делать? Решение то нужно уже сегодня написать...


Ловить исключение, вестимо. Хотя вообще делать await на отмененной задаче какой смысл? Это нужно, чтобы выполнить какой-нибудь вспомогательный код или что-то залогировать, смысл
ждать continuation
Кодом людям нужно помогать!
Re: Как лучше игнорить TaskCanceledException
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.03.20 13:12
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Если TaskCanceledException — штатная ситуация и нет смысла ее специально как-то обрабатывать. Не хочется ее отлавливать и писать пустой блок catch в нескольких местах.


этот пример пробовал?
http://rsdn.org/forum/dotnet/7674319.1
Автор: Serginio1
Дата: 06.03.20

Единственно, что TaskContinuationOptions.ExecuteSynchronously
ContinueWith(completed =>
        {
           ...
        }, CancellationToken.None,
           TaskContinuationOptions.ExecuteSynchronously,
           TaskScheduler.Default);
и солнце б утром не вставало, когда бы не было меня
Re[6]: Как лучше игнорить TaskCanceledException
От: Shmj Ниоткуда  
Дата: 16.03.20 13:42
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Ловить исключение, вестимо. Хотя вообще делать await на отмененной задаче какой смысл? Это нужно, чтобы выполнить какой-нибудь вспомогательный код или что-то залогировать, смысл

S>ждать continuation

Вот в том то и дело — не хочется писать путстые блоки try|catch(TaskCanceledException). Лучше просто игнорить.

Можно типа:

using System;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main()
    {
        var task1 = Task.Run(() => { throw new TaskCanceledException(); })
            .ContinueWith(t =>
            {
                if (t.IsFaulted)
                    throw t.Exception;
            });

        var task2 = Task.Run(() => { throw new Exception("test"); })
            .ContinueWith(t =>
            {
                if (t.IsFaulted)
                    throw t.Exception;
            });

        await task1; // Ничего

        await task2; // Exception
    }
}


Т.е. цель — игнорить отмененные (TaskCanceledException), но не терять все остальное.

Вот и думаю как красивее сделать.
Re[7]: Как лучше игнорить TaskCanceledException
От: Shmj Ниоткуда  
Дата: 16.03.20 14:00
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Вот и думаю как красивее сделать.


Пока не придумалось ничего лучше, чем такой метод:

        public static async Task IgnoreCancellation(this Task t)
        {
            try
            {
                await t;
            }
            catch (TaskCanceledException)
            {
            }
        }
Re[7]: Как лучше игнорить TaskCanceledException
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.03.20 18:41
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Sharov, Вы писали:


S>>Ловить исключение, вестимо. Хотя вообще делать await на отмененной задаче какой смысл? Это нужно, чтобы выполнить какой-нибудь вспомогательный код или что-то залогировать, смысл

S>>ждать continuation

S>Вот в том то и дело — не хочется писать путстые блоки try|catch(TaskCanceledException). Лучше просто игнорить.


S>Можно типа:


S>
S>using System;
S>using System.Threading.Tasks;

S>public class Program
S>{
S>    public static async Task Main()
S>    {
S>        var task1 = Task.Run(() => { throw new TaskCanceledException(); })
S>            .ContinueWith(t =>
S>            {
S>                if (t.IsFaulted)
S>                    throw t.Exception;
S>            });

S>        var task2 = Task.Run(() => { throw new Exception("test"); })
S>            .ContinueWith(t =>
S>            {
S>                if (t.IsFaulted)
S>                    throw t.Exception;
                 else if (t.IsCanceled)
                     throw new TaskCanceledException();
S>            });

S>        await task1; // Ничего

S>        await task2; // Exception
S>    }
S>}
S>


S>Т.е. цель — игнорить отмененные (TaskCanceledException), но не терять все остальное.


S>Вот и думаю как красивее сделать.
и солнце б утром не вставало, когда бы не было меня
Re[3]: Как лучше игнорить TaskCanceledException
От: alexsoff Россия  
Дата: 18.05.20 06:23
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Возможно даже это баг компиллера, т.к. Roslyn и .Net-классик — работают иначе.

Как иначе?
Запустил — везде появляется Task Canceled Exception.

NF:4.7.2 https://dotnetfiddle.net/IZQQL7

Roslyn https://dotnetfiddle.net/zhXxv8
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.