Приложение А. Разработка приложения обработки заказов

В этом приложении содержатся подробные действия, которые помогут разработчикам создать службу заказов Contoso. Задача этого приложения — научить разработчиков создавать приложения, включающие службы WCF (Windows Communication Foundation) и Windows Workflow Foundation (WF), с помощью среды Visual Studio 2010 и платформы .NET Framework 4. Основная часть учебного курса использует это приложение для демонстрации того, как администраторы и владельцы приложений могут использовать Microsoft AppFabric 1.1 для Windows Server для развертывания, наблюдения и диагностики приложений, включающих службы WCF и WF.

Эта служба заказов Contoso состоит из четырех перечисленных ниже приложений:

  • Служба обработки заказов — служба WCF, которая эмулирует вызов и завершение существующего приложения обработки заказов через интерфейсы веб-служб.

  • Служба отгрузки — служба WCF, которая эмулирует вызов и завершение приложения отгрузки с помощью интерфейсов API.

  • Служба рабочего процесса обработки заказов — служба рабочих процессов WF, которая управляет процессом заказа, включая получение заказа, его обработку и отгрузку.

  • Клиент службы заказов — приложение Windows Form, которое служит приложением переднего плана для службы заказов.

Примечание

Для целей этого приложения необязательно устанавливать Windows Server AppFabric. Тем не менее сначала необходимо установить файлы учебного курса по использованию интерфейса Microsoft AppFabric 1.1 для Windows Server, чтобы создать нужную для правильного построения структуру файлов приложения. Обратите внимание, что для целей этого приложения необязательно проходить учебный курс по использованию интерфейса Microsoft AppFabric 1.1 для Windows Server — достаточно установить файлы. Процедура установки учебного курса по использованию интерфейса Microsoft AppFabric 1.1 для Windows Server описана в разделе Урок 1. Начало работы. Папка C:\DublinTutorial\OrderServiceSolution\Completed содержит копию готового решения.

Процедура

Необходимо выполнить следующие процедуры, чтобы создать приложение:

  1. Разработка службы обработки заказов WCF

  2. Разработка службы отгрузки WCF

  3. Разработка службы обработки заказов WF

  4. Завершение службы обработки заказов WCF

  5. Завершение службы отгрузки WCF

  6. Разработка клиентского приложения для работы с заказами

  7. Упаковка службы заказов

Разработка службы обработки заказов WCF

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

Чтобы создать решение Visual Studio и приложение службы WCF для службы OrderProcessingService

  1. Нажмите кнопку Пуск, затем последовательно щелкните Все программы и Microsoft Visual Studio 2010 и Microsoft Visual Studio 2010.

  2. В меню Файл щелкните Создать, затем Новый проект.

  3. В окне Новый проект выберите или введите приведенные ниже значения, затем нажмите кнопку ОК.

    Свойство Значение

    Типы проектов

    Visual C#/веб

    Шаблоны

    Приложение службы WCF

    Name

    OrderProcessingService

    Location

    C:\DublinTutorial\OrderServiceSolution

    Имя решения

    OrderService

    Создать каталог для решения

    (выбрано)

  4. В обозревателе решений разверните службу OrderProcessingService, щелкните правой кнопкой мыши IService1.cs и выберите команду Удалить.

  5. Нажмите кнопку ОК для подтверждения окончательного удаления файла.

  6. В обозревателе решений разверните службу OrderProcessingService, щелкните правой кнопкой мыши Service1.svc и выберите команду Удалить.

  7. Нажмите кнопку ОК для подтверждения окончательного удаления файла.

Первой задачей при создании службы WCF является определение контракта. В контракте указано, какие операции поддерживает служба. Операция может восприниматься как метод веб-службы. Каждый метод в интерфейсе соответствует определенной операции службы. В службе OrderProcessingService следует определить два метода: ProcessOrder и CancelOrderProcess.

Чтобы определить контракт службы и контракт данных для службы обработки заказов

  1. В обозревателе решений щелкните правой кнопкой мыши службу OrderProcessService, выберите команду Добавить и щелкните пункт Новый элемент.

  2. В окне Добавление нового элемента — OrderProcessService выберите или введите перечисленные ниже значения и нажмите кнопку Добавить.

    Свойство Значение

    Категории

    Visual C#/веб

    Шаблон

    Служба WCF

    Name

    OrderProcessing.svc

    В решение добавляется два файла: IOrderProcessing.cs и OrderProcessing.svc.

  3. В обозревателе решений дважды щелкните файл IOrderProcessing.cs, чтобы открыть его.

  4. Щелкните правой кнопкой мыши пространство имен OrderProcessingService, щелкните Реструктуризация, затем Переименовать, чтобы открыть диалоговое окно Переименование.

  5. В поле Новое имя введите Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService и нажмите кнопку ОК.

  6. Нажмите кнопку Применить, затем кнопку Да.

  7. Измените исходный код OrderProcessing.svc следующим образом:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService
    {
        [ServiceContract]
        public interface IOrderProcessing
        {
            [OperationContract]
            string ProcessOrder(PurchaseOrder po);
    
            [OperationContract]
            string CancelOrderProcess(string orderID);
        }
    
        [DataContract]
        public class PurchaseOrder
        {
            [DataMember]
            public string POID;
            [DataMember]
            public string FirstName;
            [DataMember]
            public string LastName;
            [DataMember]
            public string EmailAddress;
            [DataMember]
            public string TelephoneNumber;
            [DataMember]
            public string AddressLine1;
            [DataMember]
            public string AddressLine2;
            [DataMember]
            public string City;
            [DataMember]
            public string State;
            [DataMember]
            public string ZipCode;
            [DataMember]
            public string Description;
            [DataMember]
            public int Quantity;
            [DataMember]
            public string UnitPrice;
        }
    }
    

    В этом файле следует определить контракты данных и контракты служб. Клиенты могут вызвать службы для обработки заказа, а также для отмены обработки заказа.

После создания контрактов, которые определены с помощью интерфейса, следующим шагом будет реализация интерфейса. Сюда входит создание класса с именем OrderProcessService, который реализует интерфейс IOrderProcessing.

Чтобы реализовать контракт службы обработки заказов

  1. В обозревателе решений дважды щелкните файл IOrderProcessing.cs, чтобы открыть его.

  2. Измените исходный код следующим образом:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    using System.Threading;
    using System.IO;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService
    {
        class WorkItem
        {
            private Thread workThread;
            private object workItemLock;
            private bool completeFlag;
    
            public Thread WorkThread { get { return workThread; } set { workThread = value; } }
            public object WorkItemLock { get { return workItemLock; } }
            public bool CompleteFlag { get { return completeFlag; } }
    
            public WorkItem(Thread WorkThread)
            {
                workThread = WorkThread;
                workItemLock = new object();
                completeFlag = false;
            }
    
            public void Complete()
            {
                completeFlag = true;
            }
        }
    
        public class OrderProcessing : IOrderProcessing
        {
            private static Dictionary<String, WorkItem> WorkItemMap = new Dictionary<String, WorkItem>();
    
            public string ProcessOrder(PurchaseOrder po)
            {
                //run the code from a different thread to simulate asynchronized call
                ThreadPool.QueueUserWorkItem(SendProcessResult, po);
                return ("The request for processing order[" + po.POID + "] has been received.");
            }
    
            private void SendProcessResult(object state)
            {
                PurchaseOrder po = (PurchaseOrder)state;
    
                WorkItem workItem = new WorkItem(Thread.CurrentThread);
                WorkItemMap.Add(po.POID, workItem);
    
                //Simulating the order processing process
                Thread.Sleep(120000);
    
                //The following code will be uncommented later in the process
                //OrderWorkflowService.ProcessServiceResult reply = new OrderWorkflowService.ProcessServiceResult();
                //reply.POID = po.POID;
                //reply.Message = "The order has been processed successfully.";
    
                //lock (workItem.WorkItemLock)
                //{
                //    using (OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient())
                //    {
                //        client.SubmitProcessResult(reply);
                //    }
    
                //    workItem.Complete();
                //    WorkItemMap.Remove(po.POID);
                //}
    
            }
    
            public string CancelOrderProcess(string poID)
            {
                string ret = "Cancel unavailable for this order.";
    
                //=====================================================//
                //===[ Attempt to get a work item for the order Id 
                //=====================================================//
                WorkItem workItem;
                if (WorkItemMap.TryGetValue(poID, out workItem) == true)
                {
                    //===========================================================
                    //=== Slight race condition here. Workitem could complete
                    //=== before we aquire its lock. So we check the          
                    //=== completion flag inside the lock.                    
                    //===========================================================
                    lock (workItem.WorkItemLock)
                    {
                        if ((!workItem.CompleteFlag) && (workItem.WorkThread.IsAlive))
                        {
                            workItem.WorkThread.Abort();
                            WorkItemMap.Remove(poID);
                            ret = "The order process has been terminated successfully.";
                        }
                    }
                }
                return ret;
            }
        }
    }
    

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

Чтобы настроить службу обработки заказов с помощью файла конфигурации

  1. В обозревателе решений разверните пункт OrderProcessingService, затем дважды щелкните файл Web.config для его открытия. Добавьте тег <services> в тег <system.serviceModel>:

        <services>
          <service name="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.OrderProcessing">
            <endpoint address="" binding="basicHttpBinding" contract="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.IOrderProcessing" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
    

Чтобы скомпилировать службу обработки заказов WCF

  1. В обозревателе решений щелкните правой кнопкой мыши проект OrderProcessingService и выберите команду Перестроить. В окне выхода убедитесь, что проект скомпилирован успешно.

Чтобы протестировать службу обработки заказов WCF

  1. В обозревателе решений щелкните правой кнопкой мыши проект OrderProcessingService и выберите команду Просмотреть в обозревателе. В окне Internet Explorer открывается список файлов каталога.

  2. В окне Internet Explorer щелкните файл OrderProcessing.svc. Убедитесь, что отсутствуют ошибки.

Разработка службы отгрузки WCF

Служба отгрузки — это служба WCF, которая вызывает хранилище SQL Server. В этом моделировании нет необходимости вызывать базу данных.

Чтобы добавить новый проект приложения службы WCF в решение

  1. В обозревателе решений щелкните правой кнопкой мыши решение OrderService, выберите команду Добавить и щелкните пункт Новый проект.

  2. В окне Добавление нового проекта выберите или введите приведенные ниже значения, затем нажмите кнопку ОК.

    Свойство Значение

    Типы проектов

    Visual C#/веб

    Шаблоны

    Приложение службы WCF

    Name

    ShippingService

    Location

    C:\DublinTutorial\OrderServiceSolution\OrderService

  3. В обозревателе решений разверните службу OrderProcessingService, щелкните правой кнопкой мыши IService1.cs и выберите команду Удалить.

  4. Нажмите кнопку ОК для подтверждения окончательного удаления файла.

  5. В обозревателе решений разверните службу ShippingService, щелкните правой кнопкой мыши Service1.cs и выберите команду Удалить.

  6. Нажмите кнопку ОК для подтверждения окончательного удаления файла.

Следует определить один контракт службы IShipping, который содержит два контракта операций ShipOrder и CancelShipping.

Чтобы определить контракт службы отгрузки WCF

  1. В обозревателе решений щелкните правой кнопкой мыши службу ShippingService, выберите команду Добавить и щелкните пункт Новый элемент.

  2. В окне Добавление нового элемента — ShippingService выберите или введите перечисленные ниже значения и нажмите кнопку Добавить.

    Свойство Значение

    Категории

    Visual C#/веб

    Шаблон

    Служба WCF

    Name

    Shipping.svc

    Два файла добавляются в проект: IShipping.cs и Shipping.svc.

  3. В обозревателе решений дважды щелкните файл IShipping.cs, чтобы открыть его.

  4. Щелкните правой кнопкой мыши пространство имен ShippingService, щелкните Реструктуризация, затем Переименовать, чтобы открыть диалоговое окно Переименование.

  5. В поле Новое имя введите Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService и нажмите кнопку ОК.

  6. Нажмите кнопку Применить, затем кнопку Да.

  7. Измените исходный код следующим образом:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService
    {
        [ServiceContract]
        public interface IShipping
        {
            [OperationContract]
            string ShipOrder(string poID);
    
            [OperationContract]
            string CancelShipping(string poID);
        }
    }
    

Чтобы реализовать контракт службы отгрузки WCF

  1. В обозревателе решений дважды щелкните файл Shipping.svc, чтобы открыть его.

  2. Измените исходный код следующим образом:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    using System.Threading;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService
    {
        class WorkItem
        {
            private Thread workThread;
            private object workItemLock;
            private bool completeFlag;
    
            public Thread WorkThread { get { return workThread; } set { workThread = value; } }
            public object WorkItemLock { get { return workItemLock; } }
            public bool CompleteFlag { get { return completeFlag; } }
    
            public WorkItem(Thread WorkThread)
            {
                workThread = WorkThread;
                workItemLock = new object();
                completeFlag = false;
            }
    
            public void Complete()
            {
                completeFlag = true;
            }
        }
    
        public class Shipping : IShipping
        {
            private static Dictionary<String, WorkItem> WorkItemMap = new Dictionary<String, WorkItem>();
    
            public string ShipOrder(string poID)
            {
                //run the code from a different thread to simulate asynchronized call
                ThreadPool.QueueUserWorkItem(SendShippingResult, poID);
                return ("The request for processing order[" + poID + "] has been received.");
            }
    
            private void SendShippingResult(object state)
            {
                string poID = state.ToString();
    
                WorkItem workItem = new WorkItem(Thread.CurrentThread);
                WorkItemMap.Add(poID, workItem);
    
                //Simulating the order processing process
                Thread.Sleep(60000);
    
                //The following portion will be uncommented after referencing OrderWorkflowService
                //OrderWorkflowService.ShippingServiceResult reply = new OrderWorkflowService.ShippingServiceResult();
                //reply.POID = poID;
                //reply.Message = "The order has been shipped.";
    
                //lock (workItem.WorkItemLock)
                //{
                //    using (OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient())
                //    {
                //        client.SubmitShippingResult(reply);
                //    }
    
                //    workItem.Complete();
                //    WorkItemMap.Remove(poID);
                //}
            }
    
            public string CancelShipping(string poID)
            {
                string ret = "Cancel unavailable for this order.";
    
                //=====================================================//
                //===[ Attempt to get a work item for the order Id 
                //=====================================================//
                WorkItem workItem;
                if (WorkItemMap.TryGetValue(poID, out workItem) == true)
                {
                    //===========================================================
                    //=== Slight race condition here. Workitem could complete
                    //=== before we aquire its lock. So we check the          
                    //=== completion flag inside the lock.                    
                    //===========================================================
                    lock (workItem.WorkItemLock)
                    {
                        if ((!workItem.CompleteFlag) && (workItem.WorkThread.IsAlive))
                        {
                            workItem.WorkThread.Abort();
                            WorkItemMap.Remove(poID);
                            ret = "The shipping process has been terminated successfully.";
                        }
                    }
                }
                return ret;
            }
        }
    }
    

В этом файле конфигурации следует определить две конечные точки.

Чтобы настроить службу отгрузки WCF с помощью файла конфигурации

  1. В обозревателе решений разверните пункт ShippingService, затем дважды щелкните файл Web.config для его открытия. Добавьте тег <services> в тег <system.serviceModel>:

        <services>
          <service name="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.Shipping">
            <endpoint address="" binding="basicHttpBinding" contract="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.IShipping" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
    

Чтобы скомпилировать службу отгрузки WCF

  1. В обозревателе решений щелкните правой кнопкой мыши проект ShippingService и выберите команду Перестроить. В окне выхода убедитесь, что проект скомпилирован успешно.

Разработка службы обработки заказов WF

Приложение службы рабочих процессов заказов — это основная часть всей службы. Она управляет всем бизнес-процессом. Оно получает заказ на покупку, затем вызывает службы OrderProcessingService и ShippingService и, наконец, отправляет сообщение электронной почте клиенту с уведомлением о состоянии заказа на покупку.

Чтобы добавить новый проект приложения службы рабочих процессов WCF в решение

  1. В обозревателе решений щелкните правой кнопкой мыши решение OrderService, выберите команду Добавить и щелкните пункт Новый проект.

  2. В окне Добавление нового проекта выберите или введите приведенные ниже значения, затем нажмите кнопку ОК.

    Свойство Значение

    Типы проектов

    Visual C#/рабочий процесс

    Шаблоны

    Приложение службы рабочих процессов WCF

    Name

    OrderWorkflowService

    Location

    C:\DublinTutorial\OrderServiceSolution\OrderService

Служба OrderWorkflowService использует службы OrderProcessingService и ShippingService. Необходимо предоставить ссылки на эти две службы.

Чтобы добавить ссылки на службы

  1. В обозревателе решений щелкните правой кнопкой мыши пункт OrderWorkflowService и выберите пункт Добавить ссылку на службу.

  2. В области Добавить ссылку на службу, щелкните пункт Обнаружение. Среда Visual Studio должна обнаружить обе службы.

  3. Введите и выберите приведенные ниже значения и нажмите кнопку ОК, чтобы создать ссылку на службу.

    Свойство Значение

    Службы

    OrderProcessing.svc

    Пространство имен

    OrderProcessService

  4. Повторите эти действия для добавления очередной ссылки на службу со следующими значениями:

    Свойство Значение

    Службы

    Shipping

    Пространство имен

    ShippingService

Необходимо определить пользовательское действие рабочего процесса, которое будет использоваться для моделирования отправки уведомлений по электронной почте.

Чтобы создать действие кода рабочего процесса

  1. В обозревателе решений щелкните правой кнопкой мыши службу OrderWorkflowService, выберите команду Добавить и щелкните пункт Новый элемент.

  2. В окне Добавление нового элемента — OrderWorkflowService выберите или введите перечисленные ниже значения и нажмите кнопку Добавить.

    Свойство Значение

    Категории

    Visual C#/рабочий процесс

    Шаблон

    Действие кода

    Name

    SendNotification.cs

  3. В обозревателе решений дважды щелкните файл SendNotification.cs, чтобы открыть его.

  4. Щелкните правой кнопкой мыши пространство имен OrderWorkflowService, щелкните Реструктуризация, затем Переименовать, чтобы открыть диалоговое окно Переименование.

  5. В поле Новое имя введите Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService и нажмите кнопку ОК.

  6. Нажмите кнопку Применить, затем кнопку Да.

  7. Измените исходный код следующим образом:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Activities;
    using System.IO;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService
    {
        public class SendNotification : CodeActivity
        {
            InArgument<string> to;
            InArgument<string> subject;
            InArgument<string> body;
            string pathRoot = @"C:\DublinTutorial\Inbox\";
    
            public InArgument<string> To { get { return this.to; } set { this.to = value; } }
            public InArgument<string> Subject { get { return this.subject; } set { this.subject = value; } }
            public InArgument<string> Body { get { return this.body; } set { this.body = value; } }
            public SendNotification() { }
    
            public SendNotification(InArgument<string> To, InArgument<string> Subject, InArgument<string> Body)
            {
                this.to = To; this.subject = Subject; this.body = Body;
            }
    
            protected override void Execute(CodeActivityContext context)
            {
                string filename;
                string content;
    
                try
                {
                    filename = this.to.Get<String>(context) + "~~" + this.subject.Get<string>(context) + "_" + DateTime.Now.ToFileTime() + ".txt";
                    content = String.Format("To: {0}" + Environment.NewLine
                        + "From: {1}" + Environment.NewLine
                        + "Subject: {2}" + Environment.NewLine
                        + Environment.NewLine
                        + "{3}",
                        this.to.Get<String>(context), "CustomerRelations@Contoso.com", this.subject.Get<String>(context), this.body.Get<String>(context));
    
                    File.WriteAllText((pathRoot + filename), content);
                }
                catch (Exception Ex)
                {
                    context.SetValue(Body, Ex.Message);
                }
    
            }
        }
    }
    

    Обратите внимание, что путь жестко прописан как C:\DublinTutorial\Inbox\.

В следующей процедуре следует определить типы данных. Эти типы данных используются службами OrderProcessingService и ShippingService для отправления результатов обратно в службу OrderWorkflowService.

Чтобы определить типы данных

  1. В обозревателе решений щелкните правой кнопкой мыши службу OrderWorkflowService, выберите команду Добавить и щелкните пункт Новый элемент.

  2. В окне Добавление нового элемента — OrderWorkflowService выберите или введите перечисленные ниже значения и нажмите кнопку Добавить.

    Свойство Значение

    Категории

    Visual C#/код

    Шаблон

    Файл кода

    Name

    DataTypes.cs

  3. В обозревателе решений дважды щелкните файл DataTypes.cs, чтобы открыть его.

  4. Измените исходный код следующим образом:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService
    {
        [DataContract]
        public class ProcessServiceResult
        {
            [DataMember]
            public string POID;
            [DataMember]
            public string Message;
        }
    
        [DataContract]
        public class ShippingServiceResult
        {
            [DataMember]
            public string POID;
            [DataMember]
            public string Message;
        }
    }
    
  5. В обозревателе решений щелкните правой кнопкой мыши проект OrderWorkflowService и выберите команду Перестроить. Необходимо построить проект, чтобы действие кода стало доступно из рабочего процесса, который будет создан на следующем этапе. Компиляция может также открыть для рабочего процесса конечные точки службы WCF, на которые имеются ссылки.

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

  1. Создание рабочего процесса с помощью действий.

  2. Определение переменных.

  3. Настройка действий.

Чтобы определить рабочий процесс

  1. В обозревателе решений разверните службу OrderWorkflowService, щелкните правой кнопкой мыши Service1.xamlx и выберите команду Переименовать. Переименуйте файл в OrderWorkflow.xamlx.

  2. В обозревателе решений дважды щелкните файл OrderWorkflow.xamlx, чтобы открыть его. В последовательной службе отображаются два действия: одно называется ReceiveRequest, другое — SendResponse.

  3. Щелкните правой кнопкой мыши действие Последовательная служба и выберите команду Удалить.

  4. В рабочем процессе выберите команду Перетащить действие сюда и задайте следующие значения на панели Свойства.

    Свойство Значение

    configurationName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderWorkflow

    Name

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderWorkflow

  5. Щелкните пункт Панель инструментов в левой части окна. После открытия панели инструментов прикрепите его в левой части окна.

  6. Перетащите следующие действия с панели инструментов в область рабочего процесса, помеченную как «Перетащить действие сюда».

    Категория Действие Примечание

    Блок-схема

    Блок-схема

    Действие "Блок-схема" — это составное действие, которое запускается по умолчанию. На следующих этапах сюда будут добавлены дополнительные действия.

  7. Перетащите следующие действия с панели инструментов в рабочий процесс в указанном ниже порядке:

    Категория Действие Примечание

    Сообщения

    ReceiveAndSendReply

    Это состояние «Ожидание заказа».

    Управление потоком

    Последовательность

    Здесь будет содержаться второе состояние «Заказ открыт».

    Блок-схема

    FlowDecision

    Действие FlowDecision способствует переходу между состояниями.

    Управление потоком

    Последовательность

    Здесь будет содержаться третье состояние «Заказ обработан».

    Блок-схема

    FlowDecision

    Действие FlowDecision способствует переходу между состояниями.

    Управление потоком

    Последовательность

    Здесь будет содержаться последнее состояние «Заказ выполнен».

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

    67e7c9dd-77e7-43be-ad5a-797b3b46f6e8

  9. Щелкните пункт Переменные в нижней части рабочего процесса для открытия панели Переменные.

  10. На панели Переменные щелкните пункт Создать переменную, затем создайте следующие переменные:

    Имя переменной Тип переменной Область Примечание

    poID

    Строка

    Блок-схема

    poID — это глобальный уникальный идентификатор (GUID). Идентификатор poID также используется для корреляции.

    isProcessed

    Логическое значение

    Блок-схема

    Флаг, указывающий на успешность обработки заказа.

    isShipped

    Логическое значение

    Блок-схема

    Флаг, указывающий на отгрузку заказа.

    isUpdated

    Логическое значение

    Блок-схема

    Флаг, указывающий на обновление заказа клиентом.

    po

    PurchaseOrder

    Блок-схема

    Это пользовательский тип данных, определенный в службе OrderProcessingService. В нем содержатся сведения о заказе на покупку.

    poUpdate

    PurchaseOrder

    Блок-схема

    Здесь содержатся обновления сведения по заказу на покупку при обновлении клиентом заказа на покупку.

    correlationorderWorkflow

    CorrelationHandle

    Блок-схема

    Это дескриптор корреляции, который используется как клиентом, подключающимся к службе, так и службой, подключающейся к службам OrderProcessService и ShippingService.

    Ниже приведен снимок экрана, на котором содержатся созданные переменные:

    9208977f-710c-460f-afd8-5c6bd8a792d9

  11. В рабочем процессе щелкните действие Блок-схема и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Служба заказов

  12. В рабочем процессе щелкните первое действие Последовательность и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Ожидание заказа

  13. В рабочем процессе щелкните второе действие Последовательность и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Заказ открыт

  14. В рабочем процессе щелкните третье действие Последовательность и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Заказ обработан

  15. В рабочем процессе щелкните четвертое действие Последовательность и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Заказ выполнен

  16. В рабочем процессе щелкните первое действие FlowDecision и задайте следующие значения на панели Свойства.

    Свойство Значение

    Condition

    isProcessed

    FalseLabel

    Обновлено

    TrueLabel

    Обработано

  17. В рабочем процессе щелкните второе действие FlowDecision и задайте следующие значения на панели Свойства.

    Свойство Значение

    Condition

    isShipped

    FalseLabel

    Обновлено

    TrueLabel

    Отгружено

    Была определена основная структура рабочего процесса с состояниями. Теперь следует определить каждое состояние.

  18. В рабочем процессе щелкните дважды пункт Ожидание заказа. Обратите внимание на путь, который отображается под вкладкой. Можно щелкнуть пункт Служба заказов, чтобы вернуться на страницу, где был задан весь рабочий процесс с состояниями.

  19. Перетащите следующие действия с панели инструментов в рабочий процесс в указанном ниже порядке:

    Категория Действие Примечание

    Примитивы

    Назначение

    Это действие назначения приводит к определению идентификатора заказа (GUID).

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowSerivce

    SendNotification

    Это пользовательское действие отправляет клиенту уведомление по электронной почте.

    Примитивы

    Назначение

    Это действие назначения используется для отслеживания продуктов в заказе на покупку.

    Примитивы

    Назначение

    Это действие назначения используется для отслеживания количества в заказе на покупку.

  20. Измените последовательность действий, чтобы все выглядело следующим образом:

    Ожидание действий состояния заказа

  21. Щелкните пункт Переменные в нижней части рабочего процесса для открытия панели Переменные.

  22. На панели Переменные щелкните пункт Создать переменную, затем создайте следующие переменные:

    Имя переменной Тип переменной Область Примечание

    product

    Строка

    Ожидание заказа

    Среда AppFabric способна отслеживать переменные рабочего процесса. Эта переменная создается, чтобы можно было отслеживать название продукта.

    quantity

    Int32

    Ожидание заказа

    Эта переменная служит для отслеживания.

  23. В рабочем процессе щелкните действие Получение и задайте следующие значения на панели Свойства.

    Свойство Значение

    Content

    Сообщение; данные сообщения: po; тип сообщения: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderProcessingService.Purchaseorder

    DisplayName

    Получение заказа на покупку

    OperationName

    SubmitPO

    SerivceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (выбрано)

  24. В рабочем процессе щелкните первое действие Назначение и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Назначение идентификатора заказа на покупку

    To

    po.POID

    Значение

    System.Guid.NewGuid().ToString()

  25. В рабочем процессе щелкните действие SendReplyToReceive и задайте следующие значения на панели Свойства.

    Свойство Значение

    Content

    Сообщение; данные сообщения: po.POID; тип сообщения: строка

    CorrelationInitializers

    CorrelationOrderWorkflow;инициализация корреляции запроса; key1=sm:body()/xg0:строка

    237be300-a94d-4b8e-a707-83f4d2041f6e

    Примечание

    Выполненная процедура называется корреляцией. Этот рабочий процесс содержит семь действий получения: одно связано с получением заказа на покупку; другое — с получением результатов службы обработки; третья — с получением результатов службы отгрузки; еще две — с получением клиентских обновлений и оставшиеся две — с получением клиентских отмен заказов. После получения заказа на покупку, служба рабочих процессов создает номер GUID в качестве номера заказа. Предположим, что служба рабочих процессов получает одновременно несколько заказов. Модуль рабочих процессов создает экземпляр рабочего процесса для каждого запроса заказа на покупку. Модуль рабочих процессов должен сопоставить (или скоррелировать) прочие шесть запросов с экземплярами рабочего процесса. Для этого модуль рабочих процессов нуждается в уникальном идентификаторе каждой корреляции. В этом примере уникальным идентификатором является номер заказа (GUID). В первом действии SendReplyToReceive определяется инициализатор корреляции. Следует выбрать тип запроса Инициализатор корреляции запроса, который означает, что уникальный идентификатор будет содержаться в сообщении, передаваемом в действие получения. Также следует указать xPath к этому полю. Кроме инициализатора корреляции следует указать дескриптор корреляции в поле CorrelateWith. Дескриптор корреляции — это контейнер для данных корреляции, который позволяет получать данные корреляции из любого места в рамках рабочего процесса. В последующих действиях получения следует указывать тот же дескриптор корреляции. В полях CorrelateOn fields следует указать, как следует получать номер заказа из полученного сообщения.

  26. В рабочем процессе щелкните действие SendNotification и задайте следующие значения на панели Свойства.

    Свойство Значение

    Body

    "We have received your order.  Your order number is " + po.POID

    DisplayName

    Отправка уведомления клиенту

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Received"

    To

    po.EmailAddress

  27. В рабочем процессе щелкните второе действие Назначение и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Назначение названия продукта

    To

    product

    Значение

    po.Description

  28. В рабочем процессе щелкните третье действие Назначение и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Назначение количества

    To

    quantity

    Значение

    po.Quantity

    На этом завершается реализация состояние "Ожидание заказа".

  29. Под названием вкладке щелкните пункт Служба заказов для отображения действия блок-схемы «Служба заказов».

  30. В рабочем процессе дважды щелкните действие последовательности Заказ открыт для реализации состояния.

  31. Перетащите следующие действия с панели инструментов в рабочий процесс в указанном ниже порядке:

    Категория Действие Примечание

    Примитивы

    Назначение

    Управление потоком

    Параллельное действие

  32. Перетащите следующее действие в область параллельного действия:

    Категория Действие Примечание

    Управление потоком

    Последовательность

  33. Перетащите следующее действие в область действия последовательности:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.Activities

    ProcessOrder

    Время выполнения

    Сохранение

    Сообщения

    Получение

    Microsoft.Samples.Dublin.Tutorials.OrderService.orderWorkflowService

    SendNotification

    Примитивы

    Назначение

  34. Перетащите следующее действие в область параллельного действия и справа от существующего действия последовательности:

    Категория Действие Примечание

    Сообщения

    ReceiveAndSendReply

    Действие ReceiveAndSendReply является составным действием, в котором одно действие последовательности служит оболочкой для действия получения и действия SendReplyToReceive.

  35. Перетащите следующие действия в только что добавленное действия последовательности под двумя действиями получения и SendReplyToReceive:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.Activities

    CancelOrderProcess

    Управление потоком

    Если

  36. Перетащите следующее действие в ветку Then действия If:

    Категория Действие Примечание

    Управление потоком

    Последовательность

  37. Перетащите следующие действия в только что добавленное действие последовательности:

    Последовательность Действие Примечание

    Примитивы

    Назначение

    Примитивы

    Назначение

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

  38. Перетащите следующее действие в ветку Else действия If:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

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

    Категория Действие Примечание

    Сообщения

    ReceiveAndSendReply

  40. Перетащите следующие действия в только что добавленное действия последовательности под двумя действиями получения и SendReplyToReceive:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.Activities

    CancelOrderProcess

    Управление потоком

    If

  41. Перетащите следующее действие в ветку Then действия If:

    Категория Действие Примечание

    Управление потоком

    Последовательность

  42. Перетащите следующие действия в только что добавленное действие последовательности:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

    Время выполнения

    TerminateWorkflow

  43. Перетащите следующее действие в ветку Else действия If:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

    После добавления всех действий состояние "Заказ открыт" будет выглядеть следующим образом:

    Заказ в открытом состоянии

  44. Щелкните действие последовательности в самой левой ветке параллельного действия, затем щелкните пункт Переменные в нижней части рабочего процесса для открытия панели Переменные.

  45. На панели Переменные щелкните пункт Создать переменную, затем создайте следующие переменные:

    Имя переменной Тип переменной Область Примечание

    cancelOrderProcessAcknowledgement

    Строка

    Параллельное действие

    ProcessServiceResult

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.ProcessServiceResult

    Последовательность

    processServiceAcknowledgement

    Строка

    Последовательность

  46. В рабочем процессе щелкните действие Назначение сверху параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Инициализация isUpdated

    To

    isUpdated

    Значение

    False

  47. В рабочем процессе щелкните параллельное действие и задайте следующие значения на панели Свойства.

    Свойство Значение

    Завершение

    isUpdated Or isProcessed

    DisplayName

    Обработка заказа

  48. В рабочем процессе щелкните действие Последовательность в самой левой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Обработка

  49. В рабочем процессе щелкните действие ProcessOrder в самой левой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Обработка заказа

    po

    po

    ProcessOrderResult

    processServiceAcknowledgement

  50. В рабочем процессе щелкните действие Получение в самой левой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Content

    Сообщение; данные сообщения:processServiceResult; тип сообщения: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.ProcessServiceResult

    DisplayName

    Результаты процесса получения

    OperationName

    SubmitProcessResult

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (Очищено)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow; запросы XPath: key1=sm:body()/xg0:ProcessServiceResult/sg0:POID

    CorrelationWith:

    correlationOrderWorkflow

  51. В рабочем процессе щелкните действие SendNotification в самой левой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Body

    "Order with order#" + po.POID + " has been processed, and is ready for shipping."

    DisplayName

    Отправка уведомления клиенту

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Processed"

    To

    po.EmailAddress
  52. В рабочем процессе щелкните действие Назначение в самой левой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Установка флага isProcessed

    To

    isProcessed

    Значение

    True

    Завершена настройка самой левой ветки параллельного действия.

  53. В рабочем процессе щелкните действие Последовательность в средней ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Ожидание обновления

  54. В рабочем процессе щелкните действие Получение в средней ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Content

    Сообщение; данные сообщения:poUpdate; тип сообщения: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderProcessingService.PurchaseOrder

    DisplayName

    Получение обновления

    OperationName

    SubmitUpdate

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (Очищено)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow; запросы XPath: key1=sm:body()/xg0:PurchaseOrder/xg0:POID

    CorrelationWith:

    correlationOrderWorkflow

  55. В рабочем процессе щелкните действие Последовательность в средней ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Content

    Сообщение; данные сообщения: «получено обновление заказа на покупку»; тип сообщения: строка

    DisplayName

    Подтверждение получения обновления

  56. В рабочем процессе щелкните действие CancelOrderProcess в средней ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    CancelOrderProcessResult

    cancelOrderProcessAcknowledgement

    DisplayName

    Отмена обработки заказа

    orderID

    po.POID
  57. В рабочем процессе щелкните действие If в средней ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Condition

    cancelOrderProcessAcknowledgement = "The order process has been terminated successfully."

    DisplayName

    Проверка состояния отмены

  58. В рабочем процессе щелкните действие Последовательность в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Последовательность успешной отмены

  59. В рабочем процессе щелкните первое действие Назначение в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Обновление заказа на покупку

    To

    po

    Значение

    poUpdate
  60. В рабочем процессе щелкните второе действие Назначение в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Установка флага isUpdated

    To

    isUpdated

    Значение

    True
  61. В рабочем процессе щелкните действие SendNotification в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    Body

    "Your order has updated upon your request. The order is under processing."

    DisplayName

    Отправка уведомления клиенту

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Updated (by customer)"

    To

    po.EmailAddress
  62. В рабочем процессе щелкните действие SendNotification в ветке Else действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    Body

    "Your order update request cannot be processed. Please try again."

    DisplayName

    Отправка уведомления клиенту

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Update (by customer) Failed"

    To

    po.EmailAddress

    Завершена настройка средней ветки параллельного действия.

  63. В рабочем процессе щелкните действие Последовательность в самой правой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Ожидание отмены

  64. В рабочем процессе щелкните действие Получение в самой правой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Content

    Сообщение; данные сообщения:poID; тип сообщения:строка

    DisplayName

    Получение отмены

    OperationName

    SubmitCancellation

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (Очищено)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow; запросы XPath: key1=sm:body()/xg0:строка

    CorrelationWith

    correlationOrderWorkflow

  65. В рабочем процессе щелкните действие SendReplyToReceive в самой правой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Content

    Сообщение; данные сообщения: «получена отмена заказа на покупку»; тип сообщения: строка

    DisplayName

    Подтверждение получения отмены

  66. В рабочем процессе щелкните действие CancelOrderProcess в самой правой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    CancelOrderProcessResult

    cancelOrderProcessAcknowledgement

    DisplayName

    Отмена обработки заказа

    orderID

    po.POID
  67. В рабочем процессе щелкните действие If в самой правой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Condition

    cancelOrderProcessAcknowledgement = "The order process has been terminated successfully."

    DisplayName

    Проверка состояния отмены

  68. В рабочем процессе щелкните действие Последовательность в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Последовательность успешной отмены

  69. В рабочем процессе щелкните действие SendNotification в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    Body

    "Your order has been cancelled upon your request."

    DisplayName

    Отправка уведомления клиенту

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Cancelled (by customer)"

    To

    po.EmailAddress
  70. В рабочем процессе щелкните действие TerminateWorkflow в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Прерывание рабочего процесса

    Reason

    “Client cancellation”
  71. В рабочем процессе щелкните действие SendNotification в ветке Else действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    Body

    "Your order cancellation request cannot be processed. Please try again."

    DisplayName

    Отправка уведомления клиенту

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Cancellation(by customer) Failed"

    To

    po.EmailAddress

    Завершена настройка самой правой ветки параллельного действия.

  72. Под названием вкладке щелкните пункт Служба заказов для отображения действия блок-схемы «Служба заказов».

  73. В рабочем процессе дважды щелкните действие последовательности Заказ обработан для реализации состояния.

  74. Перетащите следующие действия с панели инструментов в рабочий процесс в указанном ниже порядке:

    Категория Действие Примечание

    Примитивы

    Назначение

    Управление потоком

    Параллельное действие

  75. Перетащите следующее действие в область параллельного действия:

    Категория Действие Примечание

    Управление потоком

    Последовательность

  76. Перетащите следующее действие в область действия последовательности:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService.Activities

    ShipOrder

    Время выполнения

    Сохранение

    Сообщения

    Получение

    Примитивы

    Назначение

  77. Перетащите следующее действие в область параллельного действия и справа от существующего действия последовательности:

    Категория Действие Примечание

    Сообщения

    ReceiveAndSendReply

    Действие ReceiveAndSendReply является составным действием, в котором одно действие последовательности служит оболочкой для действия получения и действия SendReplyToReceive.

  78. Перетащите следующие действия в только что добавленное действия последовательности под двумя действиями получения и SendReplyToReceive:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService.Activities

    CancelShipping

    Управление потоком

    If

  79. Перетащите следующее действие в ветку Then действия If:

    Категория Действие Примечание

    Управление потоком

    Последовательность

  80. Перетащите следующие действия в только что добавленное действие последовательности:

    Категория Действие Примечание

    Примитивы

    Назначение

    Примитивы

    Назначение

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SendNotification

  81. Перетащите следующее действие в ветку Else действия If:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SendNotification

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

    Категория Действие Примечание

    Сообщения

    ReceiveAndSendReply

  83. Перетащите следующие действия в только что добавленное действия последовательности под двумя действиями получения и SendReplyToReceive:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService.Activities

    CancelShipping

    Управление потоком

    If

  84. Перетащите следующее действие в ветку Then действия If:

    Категория Действие Примечание

    Управление потоком

    Последовательность

  85. Перетащите следующие действия в только что добавленное действие последовательности:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SendNotification

    Время выполнения

    TerminateWorkflow

  86. Перетащите следующее действие в ветку Else действия If:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

    После добавления всех действий состояние "Заказ обработан" будет выглядеть следующим образом:

    Заказ в обработанном состоянии

  87. Щелкните действие последовательности в самой левой ветке параллельного действия, затем щелкните пункт Переменные в нижней части рабочего процесса для открытия панели Переменные.

  88. На панели Переменные щелкните пункт Создать переменную, затем создайте следующие переменные:

    Имя переменной Тип переменной Область Примечание

    cancelShippingAcknowledgement

    Строка

    Параллельное действие

    ShippingServiceResult

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.ShippingServiceResult

    Последовательность

    shippingServiceAcknowledgement

    Строка

    Последовательность

  89. В рабочем процессе щелкните действие Назначение сверху параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Инициализация isUpdated

    To

    isUpdated

    Значение

    False

  90. В рабочем процессе щелкните параллельное действие и задайте следующие значения на панели Свойства.

    Свойство Значение

    Завершение

    isUpdated Or isShipped

    DisplayName

    Отгрузка заказа

  91. В рабочем процессе щелкните действие Последовательность в самой левой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Shipping

  92. В рабочем процессе щелкните действие ShipOrder в самой левой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Отгрузка заказа

    poID

    po.POID

    ShipOrderResult

    shippingServiceAcknowledgement

  93. В рабочем процессе щелкните действие Получение в самой левой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Content

    Сообщение; данные сообщения:shippingServiceResult; тип сообщения: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.ShippingServiceResult

    DisplayName

    Получение результатов отгрузки

    OperationName

    SubmitShippingResult

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (Очищено)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow; запросы XPath: key1=sm:body()/xg0:ShippingServiceResult/xg0:POID

    CorrelationWith

    correlationOrderWorkflow

  94. В рабочем процессе щелкните действие Назначение в самой левой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Установка флага isShipped

    To

    isShipped

    Значение

    True

    Завершена настройка самой левой ветки параллельного действия.

  95. В рабочем процессе щелкните действие Последовательность в средней ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Ожидание обновления

  96. В рабочем процессе щелкните действие Получение в средней ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Content

    Сообщение; данные сообщения:poUpdate; тип сообщения: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderProcessingService.PurchaseOrder

    DisplayName

    Получение обновления

    OperationName

    SubmitUpdate

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (Очищено)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow; запросы XPath: key1=sm:body()/xg0:PurchaseOrder/xg0:POID

    CorrelationWith

    correlationOrderWorkflow

  97. В рабочем процессе щелкните действие Последовательность в средней ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Content

    Сообщение; данные сообщения: «получено обновление заказа на покупку»; тип сообщения: Строка

    DisplayName

    Подтверждение получения обновления

  98. В рабочем процессе щелкните действие CancelShipping в средней ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    CancelShippingResult

    cancelShippingAcknowledgement

    DisplayName

    Отмена отгрузки

    orderID

    poUpdate.POID
  99. В рабочем процессе щелкните действие If в средней ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Condition

    cancelShippingAcknowledgement = "The shipping process has been terminated successfully."

    DisplayName

    Проверка состояния отмены

  100. В рабочем процессе щелкните действие Последовательность в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Последовательность успешной отмены

  101. В рабочем процессе щелкните первое действие Назначение в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Обновление заказа на покупку

    To

    po

    Значение

    poUpdate
  102. В рабочем процессе щелкните второе действие Назначение в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Установка флага isUpdated

    To

    isUpdated

    Значение

    True
  103. В рабочем процессе щелкните действие SendNotification в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    Body

    "Your order has updated upon your request. The order is under processing."

    DisplayName

    Отправка уведомления клиенту

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Updated (by customer)"

    To

    po.EmailAddress
  104. В рабочем процессе щелкните действие SendNotification в ветке Else действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    Body

    "Your order update request cannot be processed. The order has been shipped."

    DisplayName

    Отправка уведомления клиенту

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Update (by customer) Failed"

    To

    po.EmailAddress

    Завершена настройка средней ветки параллельного действия.

  105. В рабочем процессе щелкните действие Последовательность в самой правой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Ожидание отмены

  106. В рабочем процессе щелкните действие Получение в самой правой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Content

    Сообщение; данные сообщения:poID; тип сообщения:строка

    DisplayName

    Получение отмены

    OperationName

    SubmitCancellation

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (Очищено)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow; запросы XPath: key1=sm:body()/xg0:строка

    CorrelationWith

    correlationOrderWorkflow

  107. В рабочем процессе щелкните действие SendReplyToReceive в самой правой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Content

    Сообщение; данные сообщения: «получена отмена заказа на покупку»; тип сообщения: Строка

    DisplayName

    Подтверждение получения отмены

  108. В рабочем процессе щелкните действие CancelShipping в самой правой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    CancelshippingResult

    cancelShippingAcknowledgement

    DisplayName

    Отмена отгрузки

    poID

    po.POID
  109. В рабочем процессе щелкните действие If в самой правой ветке параллельного действия и задайте следующие значения на панели Свойства.

    Свойство Значение

    Condition

    cancelShippingAcknowledgement = "The shipping process has been terminated successfully."

    DisplayName

    Проверка состояния отмены

  110. В рабочем процессе щелкните действие Последовательность в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Последовательность успешной отмены

  111. В рабочем процессе щелкните действие SendNotification в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    Body

    "We are sorry you chose to cancel your order. If there is anything we can do to help you with our order process or with our products or services please do not hesitate to contact us."

    DisplayName

    Отправка уведомления клиенту

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Cancelled (by cusotmer)"

    To

    po.EmailAddress
  112. В рабочем процессе щелкните действие TerminateWorkflow в ветке Then действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    DisplayName

    Прерывание рабочего процесса

    Reason

    “Client cancellation”
  113. В рабочем процессе щелкните действие SendNotification в ветке Else действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    Body

    "Your order cancellation request cannot be processed. The order has been shipped.

    DisplayName

    Отправка уведомления клиенту

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Cancellation(by customer) Failed"

    To

    po.EmailAddress

    Завершена настройка самой правой ветки параллельного действия.

  114. Под названием вкладке щелкните пункт Служба заказов для отображения действия блок-схемы «Служба заказов».

  115. В рабочем процессе дважды щелкните действие последовательности Заказ выполнен для реализации состояния.

  116. Перетащите следующие действия с панели инструментов в рабочий процесс в указанном ниже порядке:

    Категория Действие Примечание

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SendNotification

  117. В рабочем процессе щелкните действие SendNotification в ветке Else действия If и задайте следующие значения на панели Свойства.

    Свойство Значение

    Body

    "Your order has been shipped.  Thank you for shopping at contoso.com."

    DisplayName

    Отправка уведомления клиенту

    Subject

    "Contoso.com Order#" + po.POID + "~~ Order Shipped"

    To

    po.EmailAddress

    Разработка рабочего процесса завершена.

В этом файле конфигурации определяются две конечные точки и один элемент поведения.

Чтобы настроить службу рабочего процесса заказов с помощью файла конфигурации

  1. В обозревателе решений разверните пункт OrderWorkflowService, затем дважды щелкните файл Web.config для его открытия.

  2. Добавьте тег <services> в тег <system.serviceModel>.

        <services>
          <service name="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderWorkflow">
            <endpoint address="" binding="basicHttpBinding" contract="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
    

Чтобы скомпилировать службу рабочего процесса заказов

  1. В обозревателе решений щелкните правой кнопкой мыши проект OrderWorkflowService и выберите команду Перестроить. В окне выхода убедитесь, что проект скомпилирован успешно.

Завершение службы обработки заказов

Службы OrderProcessingService и OrderWorkflowService ссылаются друг на друга. Поэтому служба OrderProcessingService должна быть завершена после службы OrderWorkflowService.

Чтобы добавить ссылки на службы

  1. В обозревателе решений щелкните правой кнопкой мыши пункт OrderProcessingService и выберите пункт Добавить ссылку на службу.

  2. В области Добавить ссылку на службу, щелкните пункт Обнаружение. Среда Visual Studio должна обнаружить обе службы.

  3. Введите и выберите приведенные ниже значения и нажмите кнопку ОК, чтобы создать ссылку на службу.

    Свойство Значение

    Службы

    OrderWorkflow.xamlx

    Пространство имен

    OrderWorkflowService

Чтобы изменить файл OrderProcess.svc

  1. В обозревателе решений разверните службу OrderProcessingService и дважды щелкните файл OrderProcessing.svc, чтобы открыть его.

  2. Раскомментируйте раздел в функции SendProcessResult function, чтобы функция выглядела следующим образом:

    
    private void SendProcessResult(object state)
    {
        PurchaseOrder po = (PurchaseOrder)state;
    
        WorkItem workItem = new WorkItem(Thread.CurrentThread);
        WorkItemMap.Add(po.POID, workItem);
    
        //Simulating the order processing process
        Thread.Sleep(120000);
    
        //The following portion will be uncommented after referencing OrderWorkflowService
        OrderWorkflowService.ProcessServiceResult reply = new OrderWorkflowService.ProcessServiceResult();
        reply.POID = po.POID;
        reply.Message = "The order has been processed successfully.";
    
        lock (workItem.WorkItemLock)
        {
            using (OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient())
            {
                client.SubmitProcessResult(reply);
            }
    
            workItem.Complete();
            WorkItemMap.Remove(po.POID);
        }
    
    }
    

Чтобы скомпилировать службу обработки заказов

  1. В обозревателе решений щелкните правой кнопкой мыши проект OrderProcessingService и выберите команду Перестроить. В окне выхода убедитесь, что проект скомпилирован успешно.

Завершение службы отгрузки

Службы ShippingService и OrderWorkflowService ссылаются друг на друга. Поэтому служба ShipingService должна быть завершена после службы OrderWorkflowService.

Чтобы добавить ссылки на службы

  1. В обозревателе решений щелкните правой кнопкой мыши пункт ShippingService и выберите пункт Добавить ссылку на службу.

  2. В области Добавить ссылку на службу, щелкните пункт Обнаружение. Среда Visual Studio должна обнаружить обе службы.

  3. Введите и выберите приведенные ниже значения и нажмите кнопку ОК, чтобы создать ссылку на службу.

    Свойство Значение

    Службы

    OrderWorkflow.xamlx

    Пространство имен

    OrderWorkflowService

Чтобы изменить Shipping.svc

  1. В обозревателе решений разверните пункт ShippingService, затем дважды щелкните файл Shipping.svc для его открытия.

  2. Раскомментируйте раздел в функции SendShippingResult function, чтобы функция выглядела следующим образом:

    private void SendShippingResult(object state)
    {
        string poID = state.ToString();
    
        WorkItem workItem = new WorkItem(Thread.CurrentThread);
        WorkItemMap.Add(poID, workItem);
    
        //Simulating the order processing process
        Thread.Sleep(60000);
    
        //The following portion will be uncommented after referencing OrderWorkflowService
        OrderWorkflowService.ShippingServiceResult reply = new OrderWorkflowService.ShippingServiceResult();
        reply.POID = poID;
        reply.Message = "The order has been shipped.";
    
        lock (workItem.WorkItemLock)
        {
            using (OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient())
            {
                client.SubmitShippingResult(reply);
            }
    
            workItem.Complete();
            WorkItemMap.Remove(poID);
        }
    }
    

Чтобы скомпилировать службу отгрузки

  1. В обозревателе решений щелкните правой кнопкой мыши проект ShippingService и выберите команду Перестроить. В окне выхода убедитесь, что проект скомпилирован успешно.

Разработка клиентского приложения для работы с заказами

На этом этапе следует разработать клиентское приложение на основе Windows Form.

Чтобы добавить проект приложения Windows Form в решение

  1. В обозревателе решений щелкните правой кнопкой мыши решение OrderService, выберите команду Добавить и щелкните пункт Новый проект.

  2. В окне Добавление нового проекта выберите или введите приведенные ниже значения, затем нажмите кнопку ОК.

    Свойство Значение

    Типы проектов

    Visual C#/Windows

    Шаблоны

    Приложение Windows Forms

    Name

    OrderClient

    Location

    C:\DublinTutorial\OrderServiceSolution\OrderService

Клиент заказов (Order client) — это интерфейс для службы рабочего процесса. Необходимо добавить ссылку на службу в службу рабочих процессов.

Чтобы добавить ссылку на службу

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

  2. В области Добавить ссылку на службу, щелкните пункт Обнаружение.

  3. Введите и выберите приведенные ниже значения и нажмите кнопку ОК, чтобы создать ссылку на службу.

    Свойство Значение

    Службы

    OrderWorkflow.xamlx

    Пространство имен

    OrderWorkflowService

Чтобы разработать форму Windows Form

  1. В обозревателе решений разверните пункт OrderClient и дважды щелкните файл Form1.cs для его открытия.

  2. Щелкните правой кнопкой мыши Form1.cs, щелкните Переименовать, затем введите OrderForm.cs.

  3. При появлении запроса нажмите кнопку Да.

  4. Добавьте с панели инструментов в форму четыре элемента управления Метка, пять элементов управления TextBox и три элемента управления Кнопка.

  5. В рабочем процессе щелкните форму и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    OrderForm

    Text

    Форма заказа Contoso.com

  6. В рабочем процессе щелкните поле label1 и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    lblOrderNumber

    Text

    Номер заказа:

  7. В рабочем процессе щелкните поле label2 и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    lblEmail

    Text

    Email:

  8. В рабочем процессе щелкните поле label3 и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    lblDescription

    Text

    Description:

  9. В рабочем процессе щелкните поле label4 и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    lblQuantity

    Text

    Quantity:

  10. В рабочем процессе щелкните поле textbox1 и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    txtOrderNumber

    Enabled

    False

  11. В рабочем процессе щелкните поле textbox2 и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    txtEmail

    Text

    JohnDole@fabrikam.com

  12. В рабочем процессе щелкните поле textbox3 и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    txtDescription

    Text

    Windows 7

  13. В рабочем процессе щелкните поле textbox4 и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    txtQuantity

    Text

    10

  14. В рабочем процессе щелкните поле textbox5 и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    txtStatus

    Anchor

    Внизу, слева, справа

    Enabled

    False

    Text

    “”

  15. В рабочем процессе щелкните button1 и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    btnSubmit

    Anchor

    Снизу, справа

    Text

    Submit

    Щелчок (под вкладкой событий)

    btnSubmit_Click

  16. В рабочем процессе щелкните button2 и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    btnUpdate

    Anchor

    Снизу, справа

    Text

    Обновить

    Щелчок (под вкладкой событий)

    btnUpdate_Click

  17. В рабочем процессе щелкните button3 и задайте следующие значения на панели Свойства.

    Свойство Значение

    Name

    btnCancel

    Anchor

    Снизу, справа

    Text

    Отмена

    Щелчок (под вкладкой событий)

    btnCancel_Click

  18. В обозревателе решений щелкните правой кнопкой мыши файл OrderForm.cs и выберите команду Просмотреть код.

  19. Щелкните правой кнопкой мыши пространство имен OrderClient, щелкните Реструктуризация, затем Переименовать, чтобы открыть диалоговое окно Переименование.

  20. В поле Новое имя введите Microsoft.Samples.Dublin.Tutorials.OrderService.OrderClient и нажмите кнопку ОК.

  21. Щелкните пункт Применить.

  22. Замените этот код на следующий:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderClient
    {
        public partial class OrderForm : Form
        {
            //Delegates to make all service calls on a secondary thread
            private delegate void SubmitOrderDelegate();
            private delegate void CancelOrderDelegate();
            private delegate void UpdateOrderDelegate();
            private delegate void CallbackDelegate(string poID, string str);
    
            private SubmitOrderDelegate SubmitOrderHandler;
            private CancelOrderDelegate CancelOrderHandler;
            private UpdateOrderDelegate UpdateOrderHandler;
            private CallbackDelegate CallbackHandler;
    
            public OrderForm()
            {
                InitializeComponent();
            }
    
            private void OrderForm_Load(object sender, EventArgs e)
            {
                btnUpdate.Enabled = false;
                btnCancel.Enabled = false;
                btnSubmit.Focus();
            }
    
            #region Submit button
            private void btnSubmit_Click(object sender, EventArgs e)
            {
                btnSubmit.Enabled = false;
                btnCancel.Enabled = false;
                btnUpdate.Enabled = false;
                txtEmail.Enabled = false;
    
                txtStatus.Text = "Connecting to the Order service ...";
    
                //Executed on secondary thread so the UI thread is not blocked
                SubmitOrderHandler = new SubmitOrderDelegate(this.SubmitOrder);
                SubmitOrderHandler.BeginInvoke(null, null);
            }
    
            private void SubmitOrder()
            {
                string strMessage = "Your order has been received.";
                string strPOID = "";
    
                OrderWorkflowService.PurchaseOrder po = new OrderWorkflowService.PurchaseOrder();
                po.EmailAddress = txtEmail.Text;
                po.Description = txtDescription.Text;
                po.Quantity = System.Int32.Parse(txtQuantity.Text);
    
                //A Blocking service call executed on secondary thread
                try
                {
                    OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient();
                    strPOID = client.SubmitPO(po);
                    client.Close();
                }
                catch (Exception Ex)
                {
                    strMessage = "Error: " + Ex.Message;
                }
    
                //Make UI updates back on the primary thread
                CallbackHandler = new CallbackDelegate(this.SubmitOrderCallBack);
                this.BeginInvoke(CallbackHandler, strPOID, strMessage);
    
            }
    
            private void SubmitOrderCallBack(string strPOID, string strMessage)
            {
                //UI updates back on the primary thread
                btnUpdate.Enabled = true;
                btnCancel.Enabled = true;
    
                txtOrderNumber.Text = strPOID;
                txtStatus.Text = strMessage;
            }
            #endregion
    
            #region Update button
            private void btnUpdate_Click(object sender, EventArgs e)
            {
                btnUpdate.Enabled = false;
                btnCancel.Enabled = false;
    
                txtStatus.Text = "Connecting to the Order service ...";
    
                //Executed on secondary thread so the UI thread is not blocked
                UpdateOrderHandler = new UpdateOrderDelegate(this.UpdateOrder);
                UpdateOrderHandler.BeginInvoke(null, null);
    
            }
    
            private void UpdateOrder()
            {
                string strMessage = "Your order update request has been received.";
                string strPOID = "";
    
                OrderWorkflowService.PurchaseOrder po = new OrderWorkflowService.PurchaseOrder();
                po.POID = txtOrderNumber.Text;
                po.EmailAddress = txtEmail.Text;
                po.Description = txtDescription.Text;
                po.Quantity = System.Int32.Parse(txtQuantity.Text);
    
                try
                {
                    OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient();
                    strMessage = client.SubmitUpdate(po);
                    client.Close();
                }
                catch (Exception Ex)
                {
                    strMessage = "Error: " + Ex.Message;
                }
    
                //Make UI updates back on the primary thread
                CallbackHandler = new CallbackDelegate(this.UpdateOrderCallback);
                this.BeginInvoke(CallbackHandler, strPOID, strMessage);
    
            }
    
            private void UpdateOrderCallback(string strPOID, string strMessage)
            {
                //UI updates back on the primary thread
                btnUpdate.Enabled = true;
                btnCancel.Enabled = true;
    
                txtStatus.Text = strMessage;
            }
            #endregion
    
            #region Cancel button
            private void btnCancel_Click(object sender, EventArgs e)
            {
                btnUpdate.Enabled = false;
                btnCancel.Enabled = false;
    
                txtStatus.Text = "Connecting to the Order service ...";
    
                //Executed on secondary thread so the UI thread is not blocked
                CancelOrderHandler = new CancelOrderDelegate(this.CancelOrder);
                CancelOrderHandler.BeginInvoke(null, null);
            }
    
            private void CancelOrder()
            {
                string strInOut = txtOrderNumber.Text;
    
                try
                {
                    OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient();
                    client.SubmitCancellation(ref strInOut);
                    client.Close();
                }
                catch (Exception Ex)
                {
                    strInOut = "Error: " + Ex.Message;
                }
    
                //Make UI updates back on the primary thread
                CallbackHandler = new CallbackDelegate(this.CancelOrderCallback);
                this.BeginInvoke(CallbackHandler, txtOrderNumber.Text, strInOut);
            }
    
            private void CancelOrderCallback(string strPOID, string strMessage)
            {
                //UI updates back on the primary thread
                //btnUpdate.Enabled = true;
                //btnCancel.Enabled = true;
    
                txtStatus.Text = strMessage;
            }
            #endregion
        }
    }
    

Чтобы скомпилировать клиент заказов

  1. В обозревателе решений щелкните правой кнопкой мыши проект OrderClient и выберите команду Перестроить. В окне выхода убедитесь, что проект скомпилирован успешно.

Проверка службы заказов

Чтобы проверить службу заказов

  1. В обозревателе решений щелкните правой кнопкой мыши проект OrderClient и выберите команду Назначить запускаемым проектом.

  2. В Visual Studio щелкните меню Отладка и выберите команду Начать отладку. Должна открыться форма Windows Form.

  3. В этой форме нажмите кнопку Отправить.

  4. Откройте проводник Windows и перейдите в папку C:\DublinTutorial\Inbox.

  5. Подождите, пока в ней появятся три уведомления в виде сообщений электронной почты. На это может уйти три-четыре минуты.

Упаковка службы заказов

Чтобы упаковать службу OrderProcessingService WCF

  1. В обозревателе решений щелкните правой кнопкой мыши проект OrderProcessingService и выберите команду Параметры упаковки/публикации.

  2. Введите следующие значения:

    Свойство Значение

    Создание веб-пакета как ZIP-файла

    (выбрано)

    Местоположение для создания пакета

    C:\DublinTutorial\DeploymentPackages\OrderProcessingService.zip

    Веб-сайт IIS/имя приложения для использования на целевом сервере

    OrderService/OrderProcessingService

  3. В обозревателе решений щелкните правой кнопкой мыши проект OrderProcessingService и выберите команду Создать пакет.

  4. Повторите последнюю процедуру для создания пакетов для трех других проектов со следующими параметрами:

    Имя проекта Местоположение для создания пакета Веб-сайт IIS/имя приложения для использования на целевом сервере

    OrderWorkflowService

    C:\DublinTutorial\DeploymentPackages\OrderWorkflowService.zip

    OrderService/OrderWorkflowService

    ShippingService

    C:\DublinTutorial\DeploymentPackages\ShippingService.zip

    OrderService/ShippingService

    Примечание

    Перед упаковкой службы может понадобиться обновить адреса конечных точек для зависимых служб в файлах Web.config для отражения сервера, на котором будут развернуты пакеты.

См. также

Основные понятия

Учебник по использованию интерфейса AppFabric
Учебник по использованию Windows PowerShell

  2012-03-05