Программирование >>  Программирование с использованием ajax 

1 ... 386 387 388 [ 389 ] 390 391 392 ... 396


что будет приводить к завершению рабочего потока и генерации события Workflow Terminated. Код, добавляемый в консольное приложение для этого события по умолчанию, предусматривает лишь вывод в окно консоли сообщения о возникновении исключения, как показано ниже:

workflowRuntime.WorkflowTerminated += delegate (object sender, WorkflowTermmatedEventArgs e)

Console.WriteLine(e.Exception.Message); waitHandle.Set 0;

Здесь предполагается, что в параметре Workf lowTerminatedEventArgs содержится исключение, которое было выдано, а также экземпляр Workf lowlnstance, который привел к его выдаче.

Предоставление кода очистки

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

SequenceActivityl 1

sequenceActivit>2 1

Drop Activities Here

Drop Actwities here

Puc. 36.14. Действие ParallelActivity

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

Это и есть то самое место, где может пригодиться обработчик операций отмены. В случае генерации исключения в одной ветви ParallelActivity все остальные ветви уведомляются об этом факте выполнением в них операций отмены. Если обработчик операций отмены был определен, тогда именно он и вызывается. Он представляет собой еще один набор действий, который, по сути, планирует их выполнение. Внутри него можно предоставлять любую необходимую логику, например, в случае отправки электронного сообщения в левой ветви ParallelActivity, в этом обработчике можно обеспечить отправку другого сообщения, указывающего получателю не обращать внимания на то электронное сообщение, которое было послано ранее.

Что касается действия ParallelActivity, то стоит обратить внимание, что его название является не совсем корректным. Если вы подумали, что это действие выполняет свои дочерние действия параллельным образом и, возможно, использует потоки



(thread) для планирования выполнения действий в каждой ветви, то это не так. На самом деле ParallelActivity использует только один поток и, в сущности, выполняет сначала первое действие в первой ветви, затем второе действие во второй ветви и т.д. Очень важно разобраться в этом - дизайнеры WF выбрали этот подход для упрощения программирования рабочих потоков таким образом, чтобы конечным пользователям не требовалось ничего знать ни о потоковой обработке, ни о блокировках. При желании, чтобы части рабочего потока все-таки действительно выполнялись параллельно, можно использовать действие InvokeWorkf lowActivity для создания нового рабочего потока (или ряда рабочих потоков). Исполняющая среда тогда будет планировать выполнение нескольких рабочих потоков в разных потоках (возможно, даже с использованием разных процессоров в случае компьютера с несколькими процессорами).

Специальные действия

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

Все действия, в конечном счете, наследуются от класса System. Workf low. ComponentModel .Activity, и именно он будет использоваться в качестве базового класса в следующем практическом занятии.

Практическое занятие Создание спбциал ьного действия

1. Создайте новый проект типа консольного приложения для последовательного рабочего потока (Sequential Workflow Console) и добавьте в него новый класс по имени DebugActivity. Этот класс должен наследоваться от базового класса Activity, поэтому введите следующий код и затем добавьте конструкцию using для System.Workflow.ComponentModel:

public class DebugActivity : Activity

2. Определите в этом классе свойство, в котором будет храниться сообщение, отображаемое при выполнении данного действия, добавив строковое свойство по имени Message, как показано ниже:

public class DebugActivity : Activity {

public string Message ( get; set; }

3. При настройке действия на выполнение исполняющей средой рабочего потока вызывается его метод Execute. Поэтому добавьте такой метод, как показано в приведенном ниже коде, или же просто введите слова override Execute и нажмите клавишу <Enter>, если хотите, чтобы этот метод был создан автоматически. Этот метод должен возвращать исполняющей среде рабочего потока какое-то значение для уведомления о том, что он завершил выполнение, и метод



Execute базового класса уже это делает, из-за чего и вызывается в конце данного метода:

public class DebugActivity ; Activity {

public string Message { get; set; } protected override ActivityExecutionStatus Execute (ActivityExecutionContext executionContext)

return base.Execute(executionContext);

4. Теперь добавьте код, способный отображать сообщение во время отладки, но пропускать его при выполнении без присоединенного отладчика. Для вывода текста можно было бы использовать метод Debug.WriteLine (), но это метод условно компилируется в рабочих сборках, из-за чего в случае сборки рабочей версии библиотеки, содержащей DebugActivity, не будет отображаться никакого вывода. Поэтому вместо него необходим какой-то другой способ для определения того, выполняется ли рабочий поток с присоединенным отладчиком. У класса Debugger в пространстве имен System. Diagnostics имеется свойство IsAttached, для которого значение true устанавливается только в том случае, если текущее приложение проходит отладку, поэтому можно просто обеспечить проверку этого свойства и сделать так, чтобы сообщение выводилось на экран только в случае, если значение этого свойства равно true. Ниже приведен весь необходимый готовый код для DebugActivity: public class DebugActivity : Activity {

public string Message ( get; set; }

protected override ActivityExecutionStatus Execute (ActivityExecutionContext executionContext)

if (Debugger.IsAttached) {

Console.WriteLine(Message); Trace.WriteLine(Message);

return base.Execute(executionContext);

Sequential Workflow

}j debugActivityl

Как видно, в этом коде для вывода сообщения используются два метода - Console.WriteLine() и Trace.WriteLine(), один из которых выводит сообщение в окно консоли, а второй - в окно Output в Visual Studio. При перетаскивании действия DebugActivity из панели инструментов в область визуального конструктора рабочего потока, оно будет выглядеть так, как показано на рис. 36.15.

Это действие выглядит несколько просто по сравнению со стандартными действиями и не показывает, что свойство Рис 36 15 Действие Message является обязательным, из-за чего можно забыть ус-DebugActivity после тановить это свойство и потом удивляться, почему во время перетаскивания в об- отладки не появлялся никакой вывод. То, как можно устра-ластъ витального кошт- проблемы, будет показано в следующем практи-рукторарабачго потша занятии.



1 ... 386 387 388 [ 389 ] 390 391 392 ... 396

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика