2013-08-03 2 views
1

Я построил небольшую цепочку заданий с условными продолжениями, однако я испытываю некоторое поведение в поведении. Моя цепочка выглядит следующим образом:Непрерывное поведение задачи Продолжение:

LoadSettings (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit 
| (OnlyOnRanToCompletion) 
CheckForUpdates (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit 
| (OnlyOnRanToCompletion) 
Update (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit 
| (OnlyOnRanToCompletion) 
Cleanup (OnlyOnFaulted)-> ErrorHandler (none)-> Exit 
| (OnlyOnRanToCompletion) 
Exit 

Как я понял, эта цепь должна работать асинхронно (т.е. не в потоке пользовательского интерфейса), но один за другим (так LoadSettings -> CheckForUpdates -> ...).

LoadSettings -> CheckForUpdates -> Cleanup -> Exit -> Cleanup -> ... Кроме того, первая очистка вызывается с параметром Task id 1 в качестве параметра (это задание выполнено правильно раньше, правильно?), и эта задача имела статус «Отменено» (и я никогда не отменю задачу в любом месте).
Кто-нибудь знает, что здесь не так?

Редактирование: Хорошо, согласно msdn, если условие продолжения не выполняется, его задача отменяется. Поэтому ErrorHandler отменяется, но как я могу остановить целую цепочку (или уведомить о других продолжениях с очисткой и выйти из нее, которая была отменена)?

ответ

0

Используя команду Task.WhenAny, вы можете создать задачу, выполняемую при завершении обработчика успеха или обработчика ошибок. Выполните эту задачу с Cleanup.

Иногда сложно настроить цепи продолжения вправо, но вы можете построить довольно сложные поточные графы, используя функции комбинатора, такие как Task.WhenAny.

Если вы можете использовать async/wait, задача упростит много. Затем вы можете использовать конструкцию нормального управления. Вы также можете симулировать ожидание использования итераторов.

0

Настройка ErrorHandler -> Продолжение очистки, так как будет работать только SingleOnRanToCompletion или NotOnCanceled. Кроме того, возможно, вы могли бы упростить вещи с помощью async. Нечто подобное может работать:

try { 
    var settings = await LoadSettings(); 
    var updatesNeeded = await CheckForUpdates(settings); 
    await Update(updatesNeeded); 
} catch (Exception e) { 
    ErrorHandler(e); 
} finally { 
    Cleanup(); 
} 

Обратите внимание, что обработка ошибок и очистка будет синхронной здесь, так как вы не можете ждать в улове /, наконец, блока. Вы можете обойти это, только сохраняя исключение в переменной, которую вы позже проверяете на значение null и переходите к обработчику ошибок async.

Смежные вопросы