Asynchronous implementation in WCF and WCF asynchronous implementation
For both parties that communicate in WCF, the client can call the Service asynchronously, and the server can also implement the Service asynchronously.
Directory:
1. the WCF client calls the Service asynchronously.
2. asynchronous Implementation of the server
The asynchronous calling service of the WCF client mainly generates an asynchronous proxy class and then calls the Asynchronous Method to Implement Asynchronous calling.
Asynchronous proxy class generation:
Directly produce asynchronous proxy through SvcUtil/async;
By adding an application, click "add reference"> "advanced", and select "generate asynchronous" in the displayed dialog box ".
Part of the generated asynchronous call proxy excuse:
[System. ComponentModel. EditorBrowsableAttribute (System. ComponentModel. EditorBrowsableState. Advanced)]
Public System. IAsyncResult BeginAdd (int x, int y, System. AsyncCallback callback, object asyncState ){
Return base. Channel. BeginAdd (x, y, callback, asyncState );
}
Public void AddAsync (int x, int y ){
This. AddAsync (x, y, null );
}
Public void AddAsync (int x, int y, object userState ){
If (this. onBeginAddDelegate = null )){
This. onBeginAddDelegate = new BeginOperationDelegate (this. OnBeginAdd );
}
If (this. onEndAddDelegate = null )){
This. onEndAddDelegate = new EndOperationDelegate (this. OnEndAdd );
}
If (this. onAddCompletedDelegate = null )){
This. onAddCompletedDelegate = new System. Threading. SendOrPostCallback (this. OnAddCompleted );
}
Base. InvokeAsync (this. onBeginAddDelegate, new object [] {
X,
Y}, this. onEndAddDelegate, this. onAddCompletedDelegate, userState );
}
1. The client calls the Service asynchronously.
The client can call services asynchronously in the following ways:
1.1 directly call the Asynchronous Method:
In the generated proxy class, there is an asynchronous implementation of the Add operation defined in the service contract, such as BeginAdd \ EndAdd. You can call the BeginAdd method to call the server method asynchronously. After the BeginAdd method is called, you can execute some other operations. These operations are executed in parallel with the server Add call. The Add call is obtained through the EndAdd method.
The test code is as follows:
Client code:
IAsyncResult asyncResult = calculatorClient. BeginAdd (1, for (int I = 0; I <10; I ++)
{
Console. WriteLine (I );
}
Int resul = calculatorClient. EndAdd (asyncResult );
Console. WriteLine (string. Format ("Calculation Result: {0}", resul ));
Server code:
Public int Add (int x, int y)
{
For (int I = 0; I <20; I ++)
{
Console. WriteLine (I );
}
Console. WriteLine ("START computing ...");
Return x + y;
}
The server output is as follows:
The client output is as follows:
This method uses the EndAdd method. If the server does not complete the execution, the current thread will be blocked until the end of the asynchronously called service is completed. If the client code remains unchanged, change the service implementation to the following:
For (int I = 0; I <20; I ++)
{
Console. WriteLine (I );
}
Thread. Sleep (5000 );
Console. WriteLine ("START computing ...");
Return x + y;
If the thread is sleeping for several seconds on the server side, the client will be blocked:
1.2 asynchronous service calling through callback:
In the generated asynchronous call proxy class, you can also call the service back:
IAsyncResult asyncResult = calculatorClient. BeginAdd (1, 2,
Delegate (IAsyncResult asyncResult)
{
Int [] array = asyncResult. AsyncState as int [];
Int result = calculatorClient. EndAdd (asyncResult1 );
CalculatorClient. close ()
Console. WriteLine (string. Format ("{0} + {1} = {2}", array [0], array [1], result ));
}, New [] {1, 2 });
This method automatically calls a callback to obtain the result after the asynchronous call of the service is completed.
1.3 register an event for an Asynchronous Operation
// Asynchronous call
CalculatorClient. AddAsync (10, 36, new [] {1000 });
// Define a trigger event for asynchronous call completion
CalculatorClient. AddCompleted + = calculatorClient_AddCompleted;
Console. WriteLine ("service call completed ...");
Console. ReadKey ();
// Run the command after the asynchronous call is completed.
Privatestaticvoid calculatorClient_AddCompleted (object obj, AddCompletedEventArgs args)
{
Var array = args. UserState as int [];
Int result = args. Result;
Console. WriteLine (result );
}
2. asynchronous implementation of services:
To define a service implementation as an Asynchronous Method, set AsyncPattern of OperationContract to true and apply it to the BeginXX interface. The last two parameters of this operation must be AsyncCallback and object; there must be an EndXX (IAsyncResult asyncResult) interface that matches the asynchronous call interface. Note that EndXX (IAsyncResult asyncResult) cannot be declared as a contract interface again, that is, it cannot be marked as OperationContract.
Define a service as an asynchronous service. The contract is defined as follows:
[OperationContract (AsyncPattern = true)]
IAsyncResult BeginCalculator
(Int x, int y, AsyncCallback asyncCallback, object state );
Void EndCalculator (IAsyncResult );
In the service that implements the contract interface, the method is implemented asynchronously.
Declare the contract interface as one-way, that is, one-way, so that the client calls this service interface asynchronously. Because it does not need to wait for the server to return, the client only needs to send the message to the transport layer to return immediately.
Can I directly mark this asynchronous client call to the server as one-way, can I not generate an asynchronous proxy class (that is, the SvcUtil/Ayncs mentioned above or declare that the proxy class will be generated for asynchronous operations when adding a reference )? The answer is no, because OneWay requires that the return value of the method be void, while the Asynchronous Method requires IAsyncResult to return the most value, which is in conflict.