Механизм управления потоками Windows Workflow Foundation. Часть 2

Источник: bytemag
Андрей Колесов

Читать часть 1

После компиляции workflow-модели она может выполняться внутри любого процесса Windows, включая консольные приложения, оконные приложения, Windows-службы, Web-сервисы и Web-сайты ASP.NET. При этом каждый экземпляр workflow легко взаимодействует с хост-приложением (рис. 1).

Рис. 1. Функционирование экземпляров workflow, активностей и WRE в среде хост-приложения.

Пример: как это работает

Лучший способ понять, как работает WF, - создать простое консольное workflow-приложение. В примере мы будем вычислять факториал числа, вводимого пользователем. Для этого мы воспользуемся Visual Studio 2005, где выберем шаблон Sequential Workflow Console Application. После этого мы автоматически попадаем в workflow-конструктор (рис. 2), в котором можно работать с графическими схемами.

Для разработки программы мы будем также применять панель Toolbox, на которой выведен список доступных активностей (рис. 3). Их можно просто перетаскивать мышью в окно конструктора. Для начала мы перенесем таким образом блок While (рис. 4), который реализует повторяющийся цикл. Далее добавим внутрь блока While блок Code - именно тут будут читаться вводимые пользователем данные. После While таким же образом добавим конструкцию IfElse, и в нее тоже вставим блоки Code. Заметим, что красным восклицательным знаком будут выделены свойства, которые нужно задать перед запуском процесса.

Рис. 2. Workflow-конструктор.

Рис. 3. В Toolbox виден список доступных активностей.

Рис. 4. Вставляем блок While в процесс.

Сам процесс визуально представлен не только в workflow-конструкторе, но и в Solution Explorer. Оттуда можно попасть в окно кода, где нам нужно описать переменные:

Public class Workflow1
    Inherits SequentialWorkflowActivity
    Private num As Integer
    Private firstTime As Boolean = True

Вернемся обратно в конструктор. По красному знаку мы видим, что свойство Condition не установлено (рис. 5). Чтобы установить его, следует щелкнуть метку Property 'Condition' is not set. В окне свойств нужно раскрыть подсписок свойств (рис. 6) и ввести имя условия WhileLoopCondition - имя подпрограммы, которая будет задавать проекту условия в цикле. Можно выбрать и вариант декларативного описания условия - Declarative Rule Condition.

Код условия будет выглядеть так:

Private Sub WhileLoopCondition( _
  ByVal sender As System.Object, _
  ByVal e As System.Workflow.Activities.ConditionalEventArgs)
    If firstTime Then
      e.Result = True
      firstTime = False
    Else
      If num < 0 Then
        e.Result = True
      Else
        e.Result = False
      End If
    End If
End Sub

Рис. 5. Мы видим знак ошибки, так как условие перехода не установлено.

Рис. 6. Установка свойства Condition для блока While.

Для блока codeActivity1 мы установим свойство Name как ReadNumber, а ExecuteCode как readNum. Сам код будет таким:

Private Sub readNum( _
  ByVal sender As System.Object, _
  ByVal e As System.EventArgs)
  
  Console.WriteLine("Please enter a positive number")
  num = CInt(Console.ReadLine())
End Sub

Для ifElseBranchActivity1 установим свойство Condition как Zero и напишем код:

Private Sub Zero( _
  ByVal sender As System.Object, _
  ByVal e As System.Workflow.Activities.ConditionalEventArgs)
  If (num = 0) Then
    e.Result = True
  Else
    e.Result = False
  End If
End Sub

Для codeActivity2 зададим Name = ZeroFactorial, ExecuteCode = PrintResultForZero и введем код:

Private Sub PrintResultForZero( _
  ByVal sender As System.Object, _
  ByVal e As System.EventArgs)
    Console.WriteLine("0! is 1")
End Sub

Обратите внимание, что для правой ветви IfElse устанавливать свойство Condition не нужно - достаточно определить левое условие.

Для элемента codeActivity3 установим Name = NonZeroFactorial, ExecuteCode = PrintResult и вставим код:

Private Sub PrintResult( _
  ByVal sender As System.Object, _
  ByVal e As System.EventArgs)
  Dim fac As Integer = 1
  For i As Integer = 1 To num
    fac *= i
  Next
  Console.WriteLine(num & "! is " & fac)
End Sub

Теперь наш workflow выглядит так (рис. 7). Далее в Solution Explorer выберем Module1.vb, в котором сформируем главное консольное приложение (листинг 1). Обратите внимание - мы добавили строку Console.Readline в код, чтобы приложение не закрывалось немедленно после завершения.

Читать часть 3


Страница сайта http://185.71.96.61
Оригинал находится по адресу http://185.71.96.61/home.asp?artId=23678