Detailed analysis of callexternalmethodactivity and handleexternaleventactivity usage in Windows Workflow

Source: Internet
Author: User

As you know, workflow can call external code through two methods, namely the local service, which are callexternalmethodactivity and handleexternaleventactivity.

1. callexternalmethodactivity

When workflow needs to actively call a method in an external code, use callexternalmethodactivity

2. handleexternaleventactivity

When workflow waits for an event in the external code and responds, handleexternaleventactivity can be used.

 

Well, let's talk a little bit about it. Here is an example to introduce how to use these two types of activity:

 

1. Create a sequential workflow Library Project in vs 2008, rename workflow1.cs to wfcalltwokindsexternalmethod. CS, and drag callexternalmethodactivity and handleexternaleventactivity to it:

2. for workflow to be called, you must first declare an interface for an external method and specify the [externaldataexchange] attribute.

The code for creating iexternalmethodcalling is as follows:

[Externaldataexchange]
Public interface iexternalmethodcalling
{
Void sendmessage (string message );
Event eventhandler <externalargs. externalargs> workflowmessagechanged;
}

Note that an interface is the unique identifier of an external method, so there cannot be two external methods that implement the same interface, because workflow decides to call that external method through the interface, if there are two external methods that implement the same interface, workflow cannot distinguish which external method to call.

3. Now we can implement the local external code, that is, the code to be called by Workflow:

 

[Serializable]
Public class LocalService: iexternalmethodcalling
{
Public event eventhandler <externalargs. externalargs> uimessageupdated;
Public String message {Get; set ;}
/// <Summary>
/// The local service method called by callexternalmethodactivity, transfer the workflow ID and the message from workflow Property
/// </Summary>
/// <Param name = "message"> </param>
Public void sendmessage (string message)
{
If (null! = Uimessageupdated)
{
This. Message = message;
Externalargs. externalargs ARGs = new wfeventcalling. externalargs. externalargs (workflowenvironment. workflowinstanceid, message );
Uimessageupdated (this, argS );
}
}

Public event eventhandler <externalargs. externalargs> workflowmessagechanged;

Public void onworkflowmessagechanged (externalargs. externalargs ARGs)
{
Workflowmessagechanged (null, argS );
}
}

In this example, callexternalmethodactivity calls the sendmessage method in the external method. When onworkflowmessagechanged in the external method runs, handleexternaleventactivity is triggered.

Here, externalargs is implemented by ourselves, because the workflow instances run independently on different threads. To handleexternaleventactivity wait for the external event to trigger, you must tell handleexternaleventactivity the correct workflow instance id, in this way, when an event in an external method is promoted, the corresponding workflow instance can respond. Because the event is passed through eventargs, we can implement a parameter class containing the workflow instance ID information.

[Serializable]
Public class externalargs: externaldataeventargs
{
Public String message {Get; set ;}
Public externalargs (guid instanceid, string message)
: Base (instanceid)
{
This. Message = message;
}
}

4. Configure two activities in Workflow

Callexternalmethodactivity:

In the attribute bar of callexternalmethodactivity1, enter our defined interface iexternalmethodcalling in interfacetype.

Select the external method to be called in methodname: sendmessage. Note that this external method requires a string type parameter. Therefore, we create a message attribute in the workflow code, then, bind it to the Message attribute in the message column.

 

Handleexternaleventactivity:

Configure similar settings in the handleexternaleventactivity1 attribute. Select an external interface and wait for the event to be triggered. The only difference is that the response Event code after the external event is provided, which is created in the workflow code.

Private void handleexternaleventactivityincluinvoked (Object sender, externaldataeventargs E)
{
Externalargs. externalargs ARGs = e as externalargs. externalargs;
This. Message = This. Message + "has been handled by Workflow ";
Console. writeline (this. Message );
}

Bind the invoked column in The handleexternaleventactivity1 attribute.

The workflow settings are completed in this way.

Because we created a workflow lirbary, we cannot run it directly. Next we will create the code to run workflow.

Add a project for the console application, as shown in program. CS:

 

 

Class program: idisposable
{
Private workflowruntime _ workflowruntime;
Private guid wfinstanceid = guid. empty;
Private wfeventcalling. LocalService. LocalService = NULL;
Autoresetevent _ waithandle = new autoresetevent (false );
Public Program ()
{
Initializeworkflowruntime ();
}
Static void main (string [] ARGs)
{
Using (program instance = new program ())
{
String MSG = string. empty;
Instance. addservice (instance. _ workflowruntime );
While (true)
{
MSG = console. Readline ();
If (MSG! = "Exit ")
{

Dictionary <string, Object> wfargs = new dictionary <string, Object> ();
Wfargs. Add ("message", MSG );
Instance. runworkflow (wfargs, typeof (wfeventcalling. wfcalltwokindsexternalmethod ));
}
Else
{
Break;
}
}
}
}
Public void dispose ()
{
_ Workflowruntime. stopruntime ();
_ Workflowruntime. Dispose ();
}

Private void addservice (workflowruntime instance)
{
System. workflow. Activities. externaldataexchangeservice service = new system. workflow. Activities. externaldataexchangeservice ();
Instance. addservice (service );
LocalService = new wfeventcalling. LocalService. LocalService ();
LocalService. uimessageupdated + = new eventhandler <wfeventcalling. externalargs. externalargs> (localservice_uimessageupdated );
Service. addservice (LocalService );
}
Private void localservice_uimessageupdated (Object sender, wfeventcalling. externalargs. externalargs E)
{
This. wfinstanceid = E. instanceid;
If (null! = LocalService)
{
Wfeventcalling. externalargs. externalargs ARGs = new wfeventcalling. externalargs. externalargs (wfinstanceid ,"");
LocalService. onworkflowmessagechanged (ARGs );
}

}

Private void initializeworkflowruntime ()
{
_ Workflowruntime = new workflowruntime ();
_ Workflowruntime. workflowcompleted + = delegate (Object sender, workflowcompletedeventargs E)
{
_ Waithandle. Set ();
};
_ Workflowruntime. workflowterminated + = delegate (Object sender, workflowterminatedeventargs E)
{
Console. Write (E. Exception. Message );
_ Waithandle. Set ();
};

_ Workflowruntime. startruntime ();
}

Public void runworkflow (Dictionary <string, Object> wfargument, type workflowtype)
{
Workflowinstance instance = _ workflowruntime. createworkflow (workflowtype, wfargument );

Instance. Start ();

// Wait the workflow to complete
_ Waithandle. waitone ();
}
}

 

The addservice method registers the external method class to be called with workflow, provides a response method for the event in the external method, and transmits a value to the workflow attribute.

Run the console program in the following order:

Run the main method and pass a value to the message of the workflow attribute. callexternalmethodactivity1 runs in workflow, calls the external method sendmessage, and promotes the uimessageupdated event. uimessageupdated calls the onworkflowmessagechanged method in the external method, the handleexternaleventactivity1 wait event workflowmessagechanged and handleexternaleventactivity1 are run in response. The value of the message parameter is processed along the workflow.

 

Unless you enter "exit" in the console window, workflow will always process the input message string.

 

All the detailed code is in:

/Files/Tonnie/workflowset.rar

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.