从WCF服务调用WF工作流

从WCF服务调用WF工作流,wcf,workflow-foundation-4,Wcf,Workflow Foundation 4,我有一个定义良好的服务契约,它公开了一系列方法。我们有这个契约的典型服务实现,它与我们的MVC应用程序一起托管在IIS7中 该体系结构是一个典型的分布式应用程序,其接口在基本核心库(可重新分发)中定义,在独立服务库中实现,最后在MVC应用程序中公开实现的端点(在服务库中) 现在的情况是,其中一个现有的服务方法可能需要执行一个逻辑流程,执行该流程最多需要10分钟。在正常情况下,我们会考虑工作流服务,但所讨论的接口正在使用中,我们有一套单元测试来测试我们的服务等。我们真的无法摆脱我们的这种实现 所

我有一个定义良好的服务契约,它公开了一系列方法。我们有这个契约的典型服务实现,它与我们的MVC应用程序一起托管在IIS7中

该体系结构是一个典型的分布式应用程序,其接口在基本核心库(可重新分发)中定义,在独立服务库中实现,最后在MVC应用程序中公开实现的端点(在服务库中)

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


所以我的问题是——

  • 是否可以有一个独立的工作流来完成这个长时间运行的流程,并从我们的WCF服务调用它
  • 如果是,那么如何确保在IIS中执行我的服务的工作线程在工作流期间保持活动状态
  • 最后,客户端不需要等待来自此服务的响应。这是一种不费吹灰之力的方法。当服务启动工作流并等待其完成时,客户端调用能否立即结束
  • 当然。在WCF服务中,您将使用执行工作流定义。这将负责在WF运行时特定线程上使用WF运行时执行/跟踪每个WF实例(即不阻塞WCF i/O线程)
  • 这里没有保证。如果应用程序池因“不活动”而崩溃或计划关闭,将终止任何仍可能执行的工作流。您必须使用持久性点来确保如果WF终止,您将从以前的书签恢复
  • 是的,首先,用标记您的WCF服务方法。其次,您将从1使用
    WorkflowApplication
    实例,使用异步
    BeginRun
    启动WF,如果您关心跟踪WCF服务中的完成/错误,您可以注册必要的
    中止
    完成
    卸载
    处理程序
  • 下面是一个非常简单的例子:

    [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);
         }
    }
    
    [DataContract]
    公共类MyParametersDataContract
    {
    [数据成员(顺序=1,IsRequired=true)]
    公共字符串值
    {
    得到;
    设置
    }
    }
    公共类IMyService
    {
    [运营合同(IsOneWay=true)]
    无效剂量测量(MyParametersDataContract-someParameters);
    }
    公共类MyService:IMyService
    {
    //将WF定义保存在静态单例中,以减少活动实现的开销
    public static readonly Lazy MyWorkflow=Lazy(()=>new MyFancyWorkflow());
    公共无效剂量测量(MyParametersDataContract someParameters)
    {
    //将传入参数转换为WF参数的示例
    Dictionary workflowInputArguments=新字典
    {
    {“SomeArgument”,someParameters.SomeValue}
    };
    //为此请求创建WFA实例
    WorkflowApplication WorkflowApplication=新的WorkflowApplication(MyService.MyWorkflow.Value,workflowInputArguments);
    //挂接已完成操作的示例
    workflowApplication.Completed=(workflowCompletedArgs)=>
    {
    //工作流完成后执行某些操作
    };
    //异步调用WF的运行
    Task.Factory.fromsync(
    workflowApplication.BeginRun,
    workflowApplication.EndRun,
    空)
    .ContinueWith(runAntecent=>
    {
    //观察/记录启动WF时出现的任何异常,以免使流程崩溃
    Trace.TraceWarning(“WF未能运行:+runAntecedent.Exception.ToString());
    },
    TaskContinuationOptions.OnlyOnFaulted);
    }
    }
    
  • 当然。在WCF服务中,您将使用执行工作流定义。这将负责在WF运行时特定线程上使用WF运行时执行/跟踪每个WF实例(即不阻塞WCF i/O线程)
  • 这里没有保证。如果应用程序池因“不活动”而崩溃或计划关闭,将终止任何仍可能执行的工作流。您必须使用持久性点来确保如果WF终止,您将从以前的书签恢复
  • 是的,首先,用标记您的WCF服务方法。其次,您将从1使用
    WorkflowApplication
    实例,使用异步
    BeginRun
    启动WF,如果您关心跟踪WCF服务中的完成/错误,您可以注册必要的
    中止
    完成
    卸载
    处理程序
  • 下面是一个非常简单的例子:

    [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);
         }
    }
    
    [DataContract]
    公共类MyParametersDataContract
    {
    [数据成员(顺序=1,IsRequired=true)]
    公共字符串值
    {
    得到;
    设置
    }
    }
    公共类IMyService
    {
    [运营合同(IsOneWay=true)]
    无效剂量测量(MyParametersDataContract-someParameters);
    }
    公共类MyService:IMyService
    {
    //将WF定义保存在静态单例中,以减少活动实现的开销
    public static readonly Lazy MyWorkflow=Lazy(()=>new MyFancyWorkflow());
    公共无效剂量测量(MyParametersDataContract someParameters)
    {
    //将传入参数转换为WF参数的示例
    Dictionary workflowInputArguments=新字典
    {
    {“SomeArgument”,someParameters.SomeValue}