使用本地服務非同步執行自訂活動商務邏輯

來源:互聯網
上載者:User

通常情況下我們開發的自訂活動的商務邏輯都是寫在Execte方法中的,由於一個工作流程執行個體在單一的線程上執行,這樣當工作流程在執行到這個活動的時候,該活動就獨佔了整個工作流程的線程,如果該自訂活動需要做很長時間的任務,那麼此時就不能處理工作流程中的其他請求。所以我們不建議把所有的商務邏輯都放到Execute方法中去執行。

1.我們可以將活動的商務邏輯放到本地服務中去非同步執行,下面我們用一個例子來說明,建立一個順序型工作流程控制台項目,首先我們先寫兩個類CaryWork和CaryWorkResult,分別代表我們要執行的工作項目和返回的結果,代碼如下:

[Serializable]public class CaryWork{    public Guid InstanceId { get; set; }    public String WorkItem { get; set; }    public String ResultQueueName { get; set; }    public CaryWork( Guid InstanceId, String ResultQueueName, String WorkItem)    {        this.InstanceId = InstanceId;        this.ResultQueueName = ResultQueueName;        this.WorkItem = WorkItem;    }
}
[Serializable]public class CaryWorkResult{   public String Result { get; set; }
public CaryWorkResult(String Result) { this.Result = Result; }}

ResultQueueName 表示返回結果的隊列名稱。
InstanceId表示工作流程的id
WorkItem 表示要執行的任務


2.然後我們開始編寫本地服務的部分,首先聲明一個介面,介面中的方法將會在自訂活動中調用,代碼如下:
public interface ILongTaskServices
{
   voidDoLongTaskWork(CaryWorkworkToDo);
}

然後實現該介面,代碼如下:

public class LongTaskServices : WorkflowRuntimeService,ILongTaskServices{   private Random _random = new Random();   public void DoLongTaskWork(CaryWork workToDo)   {       ThreadPool.QueueUserWorkItem(TPWorkCallback, workToDo);       Console.WriteLine("工作項目隊列: {0}",workToDo.WorkItem);   }          private void TPWorkCallback(Object state)   {       CaryWork workitem = state as CaryWork;       WorkflowInstance instance = Runtime.GetWorkflow(workitem.InstanceId);                   Int32 msw = _random.Next(1000, 5000);       Thread.Sleep(msw);       CaryWorkResult response = new CaryWorkResult(String.Format(
"工作項目-{0}返回-{1}", workitem.WorkItem, msw)); instance.EnqueueItem(workitem.ResultQueueName, response, null, null); }}
在本地服務中我們使用線程池來執行我們要完成的任務,我們使用Thread的Sleep方法假定每項任務要執行的時間,完
成後會返回CaryWorkResult對象。
 
3.現在我們實現我們的自訂活動,代碼如下:
public partial class LongTaskActivity : Activity,IActivityEventListener<QueueEventArgs>{
public static DependencyProperty WorkItemProperty = DependencyProperty.Register("WorkItem", typeof(string), typeof(LongTaskActivity)); [DescriptionAttribute("WorkItem")] [BrowsableAttribute(true)] [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)] public string WorkItem { get{ return ((string)(base.GetValue(LongTaskActivity.WorkItemProperty)));} set{ base.SetValue(LongTaskActivity.WorkItemProperty, value);} } private String queueName = Guid.NewGuid().ToString(); public LongTaskActivity() { InitializeComponent(); } protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { ILongTaskServices longRunningService=executionContext.GetService(typeof
(ILongTaskServices)) as ILongTaskServices; WorkflowQueuingService queueService= executionContext.GetService(typeof
(WorkflowQueuingService))as WorkflowQueuingService;
WorkflowQueue queue = queueService.CreateWorkflowQueue(queueName, true); queue.RegisterForQueueItemAvailable(this); CaryWork request = new CaryWork(this.WorkflowInstanceId, queueName, WorkItem); Console.WriteLine("調用本地服務: {0}", WorkItem); longRunningService.DoLongTaskWork(request); return ActivityExecutionStatus.Executing; } public void OnEvent(object sender, QueueEventArgs e) { ActivityExecutionContext aec = sender as ActivityExecutionContext; WorkflowQueuingService queueService = aec.GetService<WorkflowQueuingService>(); WorkflowQueue queue = queueService.GetWorkflowQueue(e.QueueName); if (queue != null && queue.Count > 0) { CaryWorkResult response = queue.Dequeue() as CaryWorkResult; if (response != null) Console.WriteLine("結果為: {0}", response.Result); } queueService.DeleteWorkflowQueue(e.QueueName); aec.CloseActivity(); }
}
在自訂活動中我們去調用本地服務的方法來執行工作項目,queue工作流程隊列被建立,Execute方法中返回
ActivityExecutionStatus.Executing表示工作項目沒有執行完成,完成後會在OnEvent事件中向控制台輸出結果,並調
用AEC的CloseActivity方法來關閉活動。
 
4.設計工作流程,我們在工作流程設計工具中拖一個ParallelActivity活動,並向每個分支中拖入一個我們自訂的活動,
並設定其WorkItem屬性,
 
 
5.在宿主程式我們需要載入本地服務到工作流程引擎中,代碼如下:
static void Main(string[] args){    using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())    {        AutoResetEvent waitHandle = new AutoResetEvent(false);        workflowRuntime.WorkflowCompleted += delegate(object sender,WorkflowCompletedEventArgs e)
{waitHandle.Set();}; workflowRuntime.WorkflowTerminated+=delegate(object sender,WorkflowTerminatedEventArgs e) { Console.WriteLine(e.Exception.Message); waitHandle.Set(); }; workflowRuntime.AddService(new LongTaskServices()); WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof
(CaryLongWF.LongTaskWorkflow)); Console.WriteLine("---工作流程執行開始---"); instance.Start(); waitHandle.WaitOne(); Console.WriteLine("---工作流程執行結束---"); }}
 
6.運行程式執行結果如下:

 

從結果上我們有的時候會看到WorkItem1和WorkItem2的順序會顛倒,這是因為我們在本地服務中做了隨機的Sleep動作。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.