Повторное создание предыдущего исключения внутри ContinueWithC#

Место общения программистов C#
Ответить
Anonymous
 Повторное создание предыдущего исключения внутри ContinueWith

Сообщение Anonymous »

Введение
Некоторое время ломая голову над своим кодом, я обнаружил, что исключения обязательно не распространяются через ContinueWith:

Код: Выделить всё

int zeroOrOne = 1;
Task.Factory.StartNew(() => 3 / zeroOrOne)
.ContinueWith(t => t.Result * 2)
.ContinueWith(t => Console.WriteLine(t.Result))
.ContinueWith(_ => SetBusy(false))
.LogExceptions();
В этом примере строка SetBusy «сбрасывает» цепочку исключений, поэтому исключение деления на ноль не видно и впоследствии взрывается мне в лицо с помощью "Исключения задачи не наблюдались..."
Итак... Я написал себе небольшой метод расширения (с множеством различных перегрузок, но в основном все так делают):

Код: Выделить всё

public static Task ContinueWithEx(this Task task, Action continuation)
{
return task.ContinueWith(t =>
{
if(t.IsFaulted) throw t.Exception;
continuation(t);
});
}
Покопавшись еще немного, я наткнулся на этот пост в блоге, где он предлагает аналогичное решение, но с использованием TaskCompletionSource, который (перефразировано) выглядит так:

Код: Выделить всё

public static Task ContinueWithEx(this Task task, Action continuation)
{
var tcs = new TaskCompletionSource();
task.ContinueWith(t =>
{
if(t.IsFaulted) tcs.TrySetException(t.Exception);
continuation(t);
tcs.TrySetResult(default(object));
});
return tcs.Task;
}
Вопрос
Являются ли эти две версии строго эквивалентными? Или есть тонкая разница между throw t.Exception и tcs.TrySetException(t.Exception)?
Кроме того, тот факт, что, по-видимому, есть только один другой человек во всем Интернете, который это сделал, указывает, что мне не хватает идиоматического способа сделать это?

Подробнее здесь: https://stackoverflow.com/questions/118 ... ntinuewith
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»