从WCF服务调用WF工作流

Nik*_*hil 1 wcf workflow-foundation-4

我有一个明确定义的服务合同,它暴露了一堆方法.我们有一个这个合同的典型服务实现,它与我们的MVC应用程序一起托管在IIS 7中.

该体系结构是典型的分布式应用程序,其接口在基础核心库(可重新分发)中定义,独立服务库中的实现,最后是MVC App暴露实现的终点(在服务图书馆).

现在的情况是,这些现有服务方法之一需要执行一个逻辑过程,该过程最多可能需要10分钟才能执行.在正常情况下,我们会考虑工作流服务,但是所讨论的界面正在使用中,我们有一套单元测试来测试我们的服务等,我们真的无法摆脱我们所拥有的这种实现.


所以我的问题是 -

  1. 是否可以拥有一个独立的工作流程,可以执行这个长时间运行的过程并从我们的WCF服务中调用它?
  2. 如果是,那么我如何确保在IIS中执行我的服务的工作线程在工作流程的持续时间内保持活动状态?
  3. 最后,客户端不需要等待此服务的响应.这是一种消防方法.当服务启动工作流并等待它完成时,客户端是否可以立即呼叫结束?

Dre*_*rsh 6

  1. 当然.在您的WCF服务中,您将使用a WorkflowApplication来执行工作流定义.这将负责在WF运行时特定线程上使用WF运行时执行/跟踪每个WF实例(即不阻止WCF I/O线程).
  2. 这里没有保证.如果应用程序池崩溃或计划因"不活动"而关闭,这将终止仍可能执行的任何工作流.您必须使用持久性点来确保如果WF终止,您将从之前的书签恢复.
  3. 是的,首先,使用[OperationContract(IsOneWay = true)]标记您的WCF服务方法.其次,你将使用WorkflowApplication实例1使用异步启动WF BeginRun,如果你关心你的WCF服务跟踪完成/错误,你可以注册必要的Aborted,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);
     }
}
Run Code Online (Sandbox Code Playgroud)