2012-03-20 77 views
1

我有一個定義良好的服務合約,它公開了一堆方法。我們有一個典型的服務實現這個合同,它與我們的MVC App一起被託管在IIS 7中。從WCF服務調用WF工作流程

該體系結構是典型的分佈式應用程序,其接口在基本核心庫(可重新分發)中定義,獨立服務庫中的實現以及最終MVC應用程序暴露了實現的端點它位於服務庫內)。

現在的情況是,其中一種現有的服務方法需要執行一個可能需要10分鐘才能執行的邏輯進程。在正常的情況下,我們會考慮工作流服務,但是接口的問題很好用,我們有一套單元測試來測試我們的服務等,我們真的無法擺脫我們擁有的這個實現。


所以我的問題是 -

  1. 是否有可能有一個獨立的工作流,可以做到這一點長時間運行的進程,從我們的WCF服務調用它呢?
  2. 如果是這樣,那麼我如何確保在IIS中執行我的服務的工作線程在工作流的持續時間內保持活動狀態?
  3. 最後客戶端不需要等待這個服務的響應。這是一種失火和遺忘的方法。當服務啓動工作流並等待它完成時,客戶端調用是否可以立即結束?

回答

6
  1. 當然可以。在您的WCF服務中,您將使用WorkflowApplication來執行您的工作流程定義。這將負責在WF運行時特定線程上(即不阻塞WCF I/O線程)使用WF運行時執行/跟蹤每個WF實例。
  2. 這裏沒有保證。如果應用程序池崩潰或計劃由於「非活動」而關閉,這將終止仍在執行的任何工作流程。你將不得不使用持久點來確保如果WF被終止,你將從之前的書籤繼續。
  3. 是的,首先,用[OperationContract(IsOneWay=true)]標記您的WCF服務方法。其次,您將使用1中的WorkflowApplication實例使用異步BeginRun啓動WF,如果您關心跟蹤WCF服務中的完成/錯誤,則可以註冊必要的,Completed,Unloaded處理程序。

這裏是一個非常簡單的例子:

[DataContract] 
public class MyParametersDataContract 
{ 
    [DataMember(Order=1, IsRequired=true)] 
    public string SomeValue 
    { 
     get; 
     set; 
    } 
} 

public class IMyService 
{ 
    [OperationContract(IsOneWay=true)] 
    void DoSomething(MyParametersDataContract someParameters); 
} 

public class MyService : IMyService 
{ 
    // Hold your WF definition in a static singleton to reduce overhead of activity realization 
    public static readonly Lazy<MyFancyWorkflow> MyWorkflow = Lazy<MyFancyWorkflow>(() => new MyFancyWorkflow()); 

    public void DoSomething(MyParametersDataContract someParameters) 
    { 
     // Example of translating incoming parameters to WF args 
     Dictionary<string, object> workflowInputArguments = new Dictionary<string, object> 
     { 
      { "SomeArgument", someParameters.SomeValue } 
     }; 

     // Create a WFA instance for this request 
     WorkflowApplication workflowApplication = new WorkflowApplication(MyService.MyWorkflow.Value, workflowInputArguments); 

     // Example of hooking the completed action 
     workflowApplication.Completed = (workflowCompletedArgs) => 
     { 
      // do something when workflow has completed 
     }; 

     // Invoke the running of the WF asynchronously 
     Task.Factory.FromAsync(
           workflowApplication.BeginRun, 
           workflowApplication.EndRun, 
           null) 
           .ContinueWith(runAntecdent => 
           { 
            // Observe/log any exception with starting the WF so it doesn't crash the process 
            Trace.TraceWarning("WF failed to run: " + runAntecedent.Exception.ToString()); 
           }, 
           TaskContinuationOptions.OnlyOnFaulted); 
    } 
} 
+0

感謝德魯。只是我在尋找的那種東西。然而,在「//在工作流完成時做些事情」一點,鑑於這是一個WCF服務,我該如何提供一個回調方法(可能在相同的服務中定義)?我的WCF服務的新實例是否會創建,並在WF完成時調用回調方法? – Nikhil 2012-03-21 23:49:53

+0

哦,是的,所以如果你想做回調,你只需在回調閉包中捕獲客戶端回調通道(OperationContext.Current.GetCallbackChannel ()),然後調用回調方法即可。 – 2012-03-22 00:04:07

+0

即使我還沒有機會嘗試這種方法,我會將其標記爲答案。它似乎確實會起作用! – Nikhil 2012-03-27 10:05:39