Создание службы длительных рабочих процессов

В данном разделе описывается, как создать службу длительных рабочих процессов. Службы длительных рабочих процессов могут работать в течение долгого времени. В определенные моменты рабочий процесс может переходить в состояние бездействия в ожидании дополнительных данных. В этом случае рабочий процесс сохраняется в базе данных SQL и удаляется из памяти. При поступлении дополнительных данных экземпляр рабочего процесса снова загружается в память и его выполнение продолжается. В этом сценарии реализуется очень упрощенная система обработки заказов. Клиент отправляет первоначальное сообщение службе рабочего процесса с указанием начать заказ. Служба возвращает клиенту идентификатор заказа. С этого момента в ожидании нового сообщения от клиента служба рабочего процесса переходит в состояние бездействия и сохраняется в базе данных SQL Server. Когда клиент отправит следующее сообщение, чтобы заказать товар, служба рабочего процесса будет снова загружена в память, после чего она завершит обработку заказа. В приведенном образце кода служба возвращает строку, указывающую на то, что товар добавлен в заказ. Этот образец кода не предполагает реализацию такого приложения в реальности, скорее это простой образец, иллюстрирующий работу служб длительных рабочих процессов. В этом разделе предполагается, как создавать проекты и решения Visual Studio 2012.

Необходимые компоненты

Чтобы воспользоваться этим пошаговым руководством, необходимо установить следующее программное обеспечение:

  1. Microsoft SQL Server 2008

  2. Visual Studio 2012

  3. Microsoft .NET Framework 4.6.1

  4. Вы знакомы с WCF и Visual Studio 2012 и знаете, как создавать проекты и решения.

Настройка База данных SQL

  1. Для сохранения экземпляров служб рабочих процессов требуется установленный Microsoft SQL Server, на котором необходимо настроить базу данных для хранения выгруженных из памяти экземпляров рабочих процессов. Запустите Microsoft SQL Management Studio, нажав кнопку "Пуск ", выбрав все программы, Microsoft SQL Server 2008 и Microsoft SQL Management Studio.

  2. Нажмите кнопку Подключение, чтобы войти в экземпляр SQL Server

  3. Щелкните правой кнопкой мыши базы данных в представлении дерева и выберите "Создать базу данных"., чтобы создать новую базу данных SQLPersistenceStore.

  4. Выполните в базе данных SQLPersistenceStore файл скрипта SqlWorkflowInstanceStoreSchema.sql, расположенный в каталоге C:\Windows\Microsoft.NET\Framework\v4.0\SQL\en, чтобы настроить требуемые схемы базы данных.

  5. Выполните в базе данных SQLPersistenceStore файл скрипта SqlWorkflowInstanceStoreLogic.sql, расположенный в каталоге C:\Windows\Microsoft.NET\Framework\v4.0\SQL\en, чтобы настроить требуемую логику базы данных.

Создание службы веб-размещенного рабочего процесса

  1. Создайте пустое решение Visual Studio 2012, назовите его OrderProcessing.

  2. Добавьте в него новый проект служебного приложения рабочего процесса WCF под названием OrderService.

  3. В диалоговом окне свойств проекта выберите веб-вкладку.

    1. В разделе "Действие запуска" выберите определенную страницу и укажите Service1.xamlx.

      Workflow Service Project Web Properties

    2. В разделе "Серверы" выберите "Использовать локальный веб-сервер IIS".

      Local Web Server Settings

      Предупреждение

      Чтобы сделать этот параметр, необходимо запустить Visual Studio 2012 в режиме администратора.

      Эти шаги необходимы, чтобы настроить размещение проекта службы рабочего процесса в IIS.

  4. Откройте Service1.xamlx , если он еще не открыт и удалите существующие действия ReceiveRequest и SendResponse .

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

    Примечание.

    Если CorrelationHandle не находится в раскрывающемся списке "Тип переменной", выберите "Обзор типов " в раскрывающемся списке. Введите CorrelationHandle в поле "Имя типа", выберите CorrelationHandle в списке и нажмите кнопку "ОК".

    Add Variables

  6. Перетащите шаблон действия ReceiveAndSendReply в действие последовательной службы. Этот набор действий будет получать сообщение от клиента и возвращать ему ответ.

    1. Выберите действие "Получение" и задайте свойства, выделенные на следующем рисунке.

      Set Receive Activity Properties

      Свойство DisplayName задает имя, отображаемое для действия «Receive» в конструкторе. Свойства ServiceContractName и OperationName задают имя контракта службы и операции, которые реализуются действием Receive. Дополнительные сведения об использовании контрактов в службах рабочих процессов см. в разделе "Использование контрактов в рабочем процессе".

    2. Щелкните ссылку "Определить... в действии ReceiveStartOrder " и задайте свойства, показанные на следующем рисунке. Обратите внимание, что переключатель "Параметры" выбран, параметр с именем p_customerName привязан к переменной customerName . Это настраивает действие Получения для получения некоторых данных и привязки этих данных к локальным переменным.

      Setting the data received by the Receive activity

    3. Выберите действие SendReplyToReceive и задайте выделенное свойство, показанное на следующем рисунке.

      Setting the properties of the SendReply activity

    4. Щелкните ссылку "Определить... " в действии SendReplyToStartOrder и задайте свойства, показанные на следующем рисунке. Обратите внимание, что выбрана переключатель "Параметры" , а параметр с именем p_orderId привязан к переменной orderId . Этот параметр указывает, что действие SendReplyToStartOrder возвратит вызывающему объекту значение типа String.

      Configuring the SendReply activity content data

    5. Перетащите действие "Назначение" между действиями Receive и SendReply и задайте свойства, как показано на следующем рисунке:

      Adding an assign activity

      При этом будет создан новый идентификатор заказа, а его значение будет помещено в переменную orderId.

    6. Выберите действие ReplyToStartOrder. В окне свойств нажмите кнопку с многоточием для корреляцииInitializers. Выберите ссылку "Добавить инициализатор", введите orderIdHandle в текстовое поле инициализатора корреляции запросов для типа корреляции и выберите p_orderId в раскрывающемся списке запросов XPATH. Эти параметры показаны на следующем рисунке. Щелкните OK. При этом будет инициализирована новая корреляция между клиентом и этим экземпляром службы рабочего процесса. При получении сообщения с этим идентификатором заказа оно будет направлено этому экземпляру службы рабочего процесса.

      Adding a correlation initializer

  7. Перетащите другое действие ReceiveAndSendReply в конец рабочего процесса (за пределами последовательности , содержащей первые действия Получения и SendReply ). Оно получит второе сообщение от клиента и ответит на него.

    1. Выберите последовательность, содержащую только что добавленные действия получения и отправки и отправки, и нажмите кнопку "Переменные". Добавьте переменную, отмеченную на следующем рисунке.

      Adding new variables

      Кроме того, добавьте orderResult в область строкуSequence .

    2. Выберите действие "Получение" и задайте свойства, показанные на следующем рисунке:

      Set the Receive activity properties

      Примечание.

      Не забудьте изменить поле ServiceContractName с ../IAddItemпомощью .

    3. Щелкните ссылку "Определить... в действии ReceiveAddItem" и добавьте параметры, показанные на следующем рисунке: это настраивает действие получения для принятия двух параметров, идентификатора заказа и идентификатора упорядоченного элемента.

      Specifying parameters for the second receive

    4. Нажмите кнопку с многоточием "Корреляон" и введите orderIdHandle. В разделе "Запросы XPath" щелкните стрелку раскрывающегося списка и выберите p_orderId. При этом будет настроена корреляция второго действия Receive. Дополнительные сведения о корреляции см. в разделе "Корреляция".

      Setting the CorrelatesOn property

    5. Перетащите действие If сразу после действия ReceiveAddItem. Это действие работает аналогично инструкции IF.

      1. Задайте для свойства Condition значениеitemId=="Zune HD" (itemId="Zune HD" for Visual Basic)

      2. Перетащите действие "Назначение" в раздел "Затем", а другой в раздел Else задайте свойства действий "Назначение", как показано на следующем рисунке.

        Assigning the result of the service call

        Если условие является true разделом "Затем ", будет выполнено. Если условие является false разделом Else , выполняется.

      3. Выберите действие SendReplyToReceive и задайте свойство DisplayName, показанное на следующем рисунке.

        Setting the SendReply activity properties

      4. Щелкните ссылку "Определить ... " в действии SetReplyToAddItem и настройте ее, как показано на следующем рисунке. При этом действие SendReplyToAddItem настраивается для возврата значения в переменнойorderResult.

        Setting the data binding for the SendReply activity

  8. Откройте файл web.config и добавьте следующие элементы в <раздел поведения> , чтобы включить сохраняемость рабочих процессов.

    <sqlWorkflowInstanceStore connectionString="Data Source=your-machine\SQLExpress;Initial Catalog=SQLPersistenceStore;Integrated Security=True;Asynchronous Processing=True" instanceEncodingOption="None" instanceCompletionAction="DeleteAll" instanceLockedExceptionAction="BasicRetry" hostLockRenewalPeriod="00:00:30" runnableInstancesDetectionPeriod="00:00:02" />
              <workflowIdle timeToUnload="0"/>
    

    Предупреждение

    В приведенном выше фрагменте кода необходимо заменить имя узла и экземпляра SQL Server.

  9. Постройте решение.

Создание клиентского приложения для вызова службы рабочего процесса

  1. Добавьте в решение новый проект консольного приложения с именем OrderClient.

  2. Добавьте в проект OrderClient ссылки на следующие сборки:

    1. System.ServiceModel.dll

    2. System.ServiceModel.Activities.dll

  3. Добавьте ссылку на службу рабочего процесса и укажите OrderService в качестве пространства имен.

  4. В метод Main() клиентского проекта добавьте следующий код:

    static void Main(string[] args)
    {
       // Send initial message to start the workflow service
       Console.WriteLine("Sending start message");
       StartOrderClient startProxy = new StartOrderClient();
       string orderId = startProxy.StartOrder("Kim Abercrombie");
    
       // The workflow service is now waiting for the second message to be sent
       Console.WriteLine("Workflow service is idle...");
       Console.WriteLine("Press [ENTER] to send an add item message to reactivate the workflow service...");
       Console.ReadLine();
    
       // Send the second message
       Console.WriteLine("Sending add item message");
       AddItemClient addProxy = new AddItemClient();
       AddItem item = new AddItem();
       item.p_itemId = "Zune HD";
       item.p_orderId = orderId;
    
       string orderResult = addProxy.AddItem(item);
       Console.WriteLine("Service returned: " + orderResult);
    }
    
  5. Выполните построение решения и запустите приложение OrderClient. Клиент выведет на экран следующий текст.

    Sending start messageWorkflow service is idle...Press [ENTER] to send an add item message to reactivate the workflow service...
    
  6. Чтобы убедиться, что служба рабочего процесса сохранена, запустите СРЕДУ SQL Server Management Studio, перейдя в меню "Пуск ", выбрав "Все программы", Microsoft SQL Server 2008, SQL Server Management Studio.

    1. В области слева разверните базы данных, SQLPersistenceStore, Представления и щелкните правой кнопкой мыши System.Activities.DurableInstancing.Instances и выберите "Первые 1000 строк". В области результатов убедитесь, что отображается по крайней мере один экземпляр. Если во время работы возникнет исключение, в этой области могут быть указаны и другие экземпляры, оставшиеся от прошлых запусков. Вы можете удалить существующие строки, щелкнув правой кнопкой мыши System.Activities.DurableInstancing.Instances и выбрав "Изменить верхние 200 строк", нажав кнопку "Выполнить", выбрав все строки в области результатов и выбрав удаление. Чтобы проверить, что в базе данных отображается экземпляр, созданный учебным приложением, перед запуском клиента удалите все записи из представления экземпляров. После запуска клиента выполните этот запрос («Выделить 1000 верхних строк») еще раз и удостоверьтесь, что новый экземпляр добавлен.
  7. Нажмите клавишу ВВОД, чтобы отправить сообщение о добавлении товара службе рабочего процесса. Клиент выведет на экран следующий текст.

    Sending add item messageService returned: Item added to orderPress any key to continue . . .
    

См. также