client.Open();//打开WCF客户端
client.GetAllCcCommunicateCompleted += new EventHandler<GoSun.WcfFache.CCMan.GetAllCcCommunicateCompletedEventArgs>(client_GetAllCcCommunicateCompleted);//注册事件句柄,用于异步执行完毕后通知界面client.GetAllCcCommunicateAsync();//异步调用

解决方案 »

  1.   

    http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/1f6679b0-680f-413a-833e-58605bb7b217/
    http://www.codeproject.com/KB/XML/MTOMWebServices.aspx
      

  2.   


      Search    Articles Authors     Advanced Search
    Sitemap  
     Print Broken Article? Book  Discuss  Send to a friend 
     4 votes for this article.      
     
    Popularity: 2.86. Rating: 4.75 out of 5. 
     
     
    Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report this article.Download source 
    Contents
    Features 
    Introduction 
    Concept and Design Implementation 
    Test 
    Appendix 
    Conclusion 
    Features
    Microsoft Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Technologies 
    No custom activity to receive an event message 
    Based on mapping the interface contracts between the WCF and Workflow technologies 
    Transaction support 
    Declaratively programming 
    No require to build a Local Service 
    Null Workflow Local Service for correlated events 
    Null WCF Service 
    Capability of the pre/post processing in the operation invoker 
    Working side by side with a Workflow Local Service (ExternalDataExchangeService) 
    Introduction
    The Microsoft WF Technology enables to receive external (host) events via a tightly coupled Local Service layer. This layer simplifies the connectivity between the workflow and host application based on the delegate/event pattern. All this magic plumbing is hidden by ExternalDataExchangeService class that intercepts a Local Service and generates an event message to the specific Workflow queue. In order to receive an event message by event driven Activity, the ExternalDataExchange interface contract must be declared with an application specific event handler. The event delegate has a standard .Net signature shown in the following line: public void EventHandler(object sender, ExternalDataEventArgs eventArgs);
    where the eventArgs represents a Workflow event interest such as InstanceId, Identity, application specific data, etc.The interface contract metadata is used to create a unique workflow queue based on the interface type, event name and collection of the properties for correlation pattern as an additional option. Note, the workflow queue messaging is the only way how the host application can talk to the workflow. From the connectivity point of the view, the Workflow represents an event sink and the WCF client's event source (subscriber interest). The following picture shows this logical pattern:On the event source side, we can create many kinds of patterns (such as Remoting, WSE, WCF, etc.) to generate an event message and send it to the local or remote workflow queue. This article describes how this connectivity cab be achieved using the WCF paradigm based on the interface contracts defined differently at each end sides. You will see how event source can be logically (declaratively) connected with the event sink metadata together.The following picture shows a representation of the loosely coupled connectivity between the WCF event source and WF event sink: Note, the Workflow side doesn't need to have the Local Service layer in order to generate an event message. For this WCF/WF plumbing we need only metadata of the interface contracts and of course a generic decorator of the operation in order to make all magic work. The service operation contract can be mapped to the specific WF interface contract explicitly using the WorkflowFireEventAttribute. Behind this attribute is a plumbing code to generate an event message and that is sent to the workflow queue. Using the WCF connectivity to deliver an event message to the Workflow event sink (such as HandleExternalEventActivity) enables building an application model with a capability of the WCF paradigm based on the Address, Binding and Contract. For example: the netMsmgBinding binding for delivery event message in the async and disconnected manner or the webHttpBinding binding to enable a connectivity for delivery an event message from the browser driven by Ajax/Json (Orcas CTP version). Let's look at in detail, how the WCF/WF plumbing is done for dispatching an even message to the workflow queue. I will assume that you are familiar with these technologies. In addition, I mentioned earlier, the Workflow side doesn't use any custom activity for this plumbing, so it is a standard workflow definition (sequential or state machine) using a HandleExternalEventActivity, therefore I will focus on the plumbing concept and implementation.Concept and Design Implementation
    The concept of the loosely coupled WCF/WF connectivity for sending a workflow event message is based on the interceptor (WorkflowFireEventAttribute) on the service operation contract, which will map it to the specific ExternalDataExchange interface contract (see the above picture).The WCF service is hosted in the same appDomain with a WorkflowRuntime. Basically we need to create a Null Service derived from our WCF Interface contract. The following is an example of the simple Null service and Interface contracts:// WCF
                [ServiceContract]
                public interface IFireEventTest
                {
                [OperationContract(IsOneWay = true)]
                void Approve(object sender, ExternalDataEventArgs e);
                }
                public class ServiceTest1 : IFireEventTest
                {
                [WorkflowFireEvent(EventType = typeof(IWorkflowSimpleEvents))]
                public void Approve(object sender, ExternalDataEventArgs e) { }
                }
                // Workflow EventType
                [ExternalDataExchange]
                public interface IWorkflowSimpleEvents
                {
                event EventHandler<ExternalDataEventArgs> Approve;
                }
                
    During the start up appDomain, the WorkflowFireEventAttribute will insert a WorkflowFireEventOperationInvoker to the OperationInvoker to intercept a call before invoking a service method. The following code snippet shows a method, where it is going to dispatch a workflow event message:  Collapse
    object IOperationInvoker.Invoke(object instance, object[] inputs, out object[] outputs)
                {
                object retVal = null;
                outputs = new object[0];
                // validation for mandatory inputs
                if (inputs.Length < 2 || !typeof(ExternalDataEventArgs).IsInstanceOfType(inputs[1]))
                throw new InvalidOperationException(string.Format(" ... ");
                // mandatory inputs
                object sender = inputs[0];
                ExternalDataEventArgs eventArgs = inputs[1] as ExternalDataEventArgs;
                if (Transaction.Current != null &&
                Transaction.Current.TransactionInformation.Status == TransactionStatus.Active)
                {
                WorkflowInstance workflowInstance = null;
                eventArgs.WaitForIdle = false;
                   #region action - transactional delivery to the workflow queue 
                using(TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))
                {
                // pre-processing
                if (this.Option == WorkflowFireEventOption.After)
                {
                retVal = this._innerOperationInvoker.Invoke(instance, inputs, out outputs);
                }
                // fire event
                workflowInstance =
                WorkflowHelper.DispatchEvent(this.EventType,this.EventName,sender,eventArgs,true);
                // storing a workflow into the database
                workflowInstance.Unload();
                // post-process
                if (this.Option == WorkflowFireEventOption.Before)
                {
                retVal = this._innerOperationInvoker.Invoke(instance, inputs, out outputs);
                }
                // done
                ts.Complete();
                }
                try
                {
                // workaround to detect WorkflowStatus
                workflowInstance.Start();
                }
                catch (Exception ex)
                {
                // WorkflowStatus != Created (therefore we can go ahead and use it)
                Trace.WriteLine(ex.Message);
                }
                   #endregion
                }
                else
                {
                   #region action - non-transactional delivery to the workflow queue
                // pre-processing
                if (this.Option == WorkflowFireEventOption.After)
                {
                retVal = this._innerOperationInvoker.Invoke(instance, inputs, out outputs);
                }
                // dispatching event
                WorkflowHelper.DispatchEvent(this.EventType, this.EventName, sender, eventArgs);
                // post-processing
                if (this.Option == WorkflowFireEventOption.Before)
                {
                retVal = this._innerOperationInvoker.Invoke(instance, inputs, out outputs);
                }
                   #endregion
                }
                return retVal;
                }