CallExternalMethod用于工作流向宿主进程中通信 简单的介绍一下它的使用技巧,参照网上的一个questioner源码进行了改进,因为我感觉这个源码提供的通信demo过于繁琐。
看看service代码
namespace QuestionService { [ExternalDataExchange] public interface ITestService { void SendResponseDataToHost(TestPara responses); } }
TestPara对象是对参数的一个封装,因为按照我的测试,在调用接口方法中,方法的参数如果不是对象类型,就会无法解决工作流传参的问题。
namespace QuestionService { [Serializable] public class TestArgs : ExternalDataEventArgs { protected TestPara _dataValue = null; public TestPara Responses { get { return _dataValue; } } public TestArgs(Guid instanceId, TestPara responses) : base(instanceId) { _dataValue = responses; } } [Serializable] public class TestPara { protected bool[] _dataValue = null; public bool[] Responses { get { return _dataValue; } set { _dataValue = value; } } } }
这是实现的关键地方,DataAvailable事件用于向宿主进程暴露
namespace QuestionService { [Serializable] public class TestService : ITestService { #region ITestService 成员 public event EventHandler<TestArgs> DataAvailable; public void SendResponseDataToHost(TestPara responses) { if (DataAvailable != null) { try { DataAvailable(this, new TestArgs(WorkflowEnvironment.WorkflowInstanceId, responses)); } catch (Exception ex) { } } // if } #endregion } }
在工作流中 要设置相关的接口协议,选择调用的方法
需要注意的是 参数要在工作流中设置参数的属性 以供其选择,其中_response是工作流活动返回的数据,这里通过TestPara属性进行封装获取
private bool[] _response = null; private TestPara _TestPara = new TestPara(); public TestPara TestPara { get { _TestPara.Responses = _response; return _TestPara; } }
最后是宿主调用的过程 对调用进行了改动 DataAvailable事件暴露给宿主进程。以供工作流进程调用。
private void cmdExecute_Click(object sender, EventArgs e) { // Disable the execute button cmdExecute.Enabled = false; // Clear the indicators ClearIndicators(); // Set the cursor to "app starting" Cursor = Cursors.AppStarting; // Process the request, starting by creating the parameters Dictionary<string, object> parms = new Dictionary<string, object>(); parms.Add("Dependent", cmbQuestionType.SelectedIndex == 0); string[] questions = new string[3]; questions[0] = tbQuestion1.Text; questions[1] = tbQuestion2.Text; questions[2] = tbQuestion3.Text; parms.Add("Questions", questions); // Create instance. _workflowInstance = _workflowRuntime.CreateWorkflow(typeof(QuestionFlow.Workflow1), parms); if (_dataExchangeService==null) { _dataExchangeService = new ExternalDataExchangeService(); _workflowRuntime.AddService(_dataExchangeService); TestService _testService = new TestService(); _testService.DataAvailable += new EventHandler<QuestionService.TestArgs>(dataService_DataAvailable); _dataExchangeService.AddService(_testService); } // Hook returned data event //QuestionService.WorkflowResponseDataService dataService = QuestionService.WorkflowResponseDataService.CreateDataService(_workflowInstance.InstanceId, _workflowRuntime); // Start instance. _workflowInstance.Start(); } public void dataService_DataAvailable(object sender, QuestionService.TestArgs e) { IAsyncResult result = this.BeginInvoke( new EventHandler( delegate { // Retrieve connection. //QuestionService.WorkflowResponseDataService dataService = QuestionService.WorkflowResponseDataService.GetRegisteredWorkflowDataService(e.InstanceId); // Read the response data bool[] responses = e.Responses.Responses; // Bind the vehicles list to the vehicles table SetIndicators(responses); } // delegate ), null, null ); // BeginInvoke this.EndInvoke(result); // Reset for next request WorkflowCompleted(); } private delegate void WorkflowCompletedDelegate(); private void WorkflowCompleted() { IAsyncResult result = this.BeginInvoke( new EventHandler( delegate { // Reset the cursor Cursor = Cursors.Arrow; // Enable the execute button cmdExecute.Enabled = true; } // delegate ), null, null ); // BeginInvoke this.EndInvoke(result); }
时间: 2024-10-29 19:09:03