WF3.0 CallExternalMethod使用技巧

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

WF3.0 CallExternalMethod使用技巧的相关文章

VC6.0实用小技巧

VC6.0的若干实用小技巧 1.检测程序中的括号是否匹配 把光标移动到需要检测的括号(如大括号{}.方括号[].圆括号()和尖括号<>)前面,键入快捷键 “Ctrl+]”.如果括号匹配正确,光标就跳到匹配的括号处,否则光标不移动,并且机箱喇叭还会发出一 声警告声. 2.查看一个宏(或变量.函数)的宏定义 把光标移动到你想知道的一个宏上,就比如说最常见的DECLARE_MAP_MESSAGE上按一下F12(或右键 菜单中的Go To Defition Of …),如果没有建立Browse fil

HDU 4509 湫湫系列故事——减肥记II(线段树-区间覆盖 或者 暴力技巧)

http://acm.hdu.edu.cn/showproblem.php?pid=4509 题目大意: 中文意义,应该能懂. 解题思路: 因为题目给的时间是一天24小时,而且还有分钟.为了解题方便,我们将小时换成分钟,那么一天24小时,总共有1440分钟.顾我就可以把一天里的任意HH:MM时间换成分钟.就这样一天的时间就变成[0,1440]区间了. 因为所给的活动最多是5*10^5,如果把活动的时间在线段[0,1440]都修改,那么时间的复杂度最坏是O(5*10^5*1440). (1)方法一

linux 小技巧总结

(1)linux判断文件是否存在 if [ -f filename]: then      ......#要执行的语句 fi 具体例子: file=/usr/local/oracle/oradata/archived_log/file.txt if [ -f $file ];then             #判断文件是否存在,存在就追加   echo $file_i >> $file   else                               #否则复写   echo $fil

.Net常用技巧_动态加载Dll

原理如下: 1.利用反射进行动态加载和调用. Assembly ass=Assembly.LoadFrom(DllPath); //利用dll的路径加载,同时将此程序集所依赖的程序集加载进来,需后辍名.dll Assembly.LoadFile 只加载指定文件,并不会自动加载依赖程序集.Assmbly.Load无需后辍名 2.加载dll后,需要使用dll中某类. Type type=ass.GetType(“TypeName”);//用类型的命名空间和名称获得类型 3.需要实例化类型,才可以使用

.Net常用技巧_打印DataGridView(转)

选择相应的列进行打印报表.只需实例化带一个DataGridView参数的构造函数就可以使用 class PrintGridViewData { public PrintGridViewData() { } private DataGridView DGridView; public PrintGridViewData(DataGridView DGView) { DGridView = DGView; } private Form dialogForm = new Form(); private

HDU4907小技巧

原题http://acm.hdu.edu.cn/showproblem.php?pid=4907 Task schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 692    Accepted Submission(s): 334 Problem Description 有一台机器,而且给你这台机器的工作表,工作表上有n个任

【Unity3D技巧】在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信

作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 在前面两篇文章: [Unity3D基础教程]给初学者看的Unity教程(四):通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D [Unity3D基础教程]给初学者看的Unity教程(三):通过制作Flappy Bird了解Native 2D中的Sprite,Animation 我们了解

VC 绘图技巧--自定义形状图形

自定义形状图形,定义几个点围城的图形,然后进行描边和填充: [cpp] view plaincopy if (m_memDC.m_hDC!=NULL) { CPoint point[4]; point[0].x=nLeft+(int)(0.1*m_nWidth); point[0].y=m_nYmargin; point[1].x=nLeft+(int)(0.9*m_nWidth); point[1].y=m_nYmargin; point[2].x=nLeft+(int)(0.7*m_nWid

工作中总结的编程小技巧

技巧一:int-->bool要注意的!bool a=255; bool b= 254; 理论上应该认为a==b,但是根据编译器的不同,结果可能完全不一样 所以更好的写法是 char ch =1; 或者0bool a = (0 != atoi(ch)); 技巧二:将std::string转int,double先利用c_str()转成C string,再用atoi()与atof() 技巧三:const_cast操作符可以强置去除const指针的const属性 技巧四:CString读取文本的每一行C