Async methods execution
Why the Begin and End methods aren't executed then the synchronous operation is defined in the service interface?
Here is an example at the end of article: http://www.danrigsby.com/blog/index.php/2008/03/26/async-operations-in-wcf-iasyncresult-model-server-side/
I've added some debug information:
public double GetSquareRoot(double value)
{
System.Diagnostics.Debugger.Log(0, "MyService", "Get - Start\n");
Thread.Sleep(3000);
System.Diagnostics.Debugger.Log(0, "MyService", "Get - Finish\n");
return Math.Sqrt(value);
}
public IAsyncResult BeginGetSquareRoot(double value, AsyncCallback callback, object state)
{
System.Diagnostics.Debugger.Log(0, "MyService", "Begin - Start\n");
GetSquareRootAsyncResult asyncResult = new GetSquareRootAsyncResult(callback, state);
asyncResult.Value = value;
ThreadPool.QueueUserWorkItem(new WaitCallback((Callback)), asyncResult);
System.Diagnostics.Debugger.Log(0, "MyService", "Begin - Finish\n");
return asyncResult;
}
public double EndGetSquareRoot(IAsyncResult asyncResult)
{
System.Diagnostics.Debugger.Log(0, "MyService", "End - Start\n");
double result = 0;
using (GetSquareRootAsyncResult getSquareRootAsyncResult = asyncResult as GetSquareRootAsyncResult)
{
getSquareRootAsyncResult.AsyncWaitHandle.WaitOne();
result = getSquareRootAsyncResult.Result;
}
System.Diagnostics.Debugger.Log(0, "MyService", "End - Finish\n");
return result;
}
For the original code the test results are:
- Get - Start
- Get - Finish
Then I delete GetSquareRoot method from IMyService, I've got:
- Begin - Start
- Begin - Finish
- Callback - Start
- Get - Start
- Get - Finish
- Callback - Finish
- End - Start
- End - Finish
What is the reason?
Client code:
public partial class Form1 : Form
{
IMyService m_Client;
public Form1()
{
InitializeComponent();
ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>("netTcp");
factory.Open();
m_Client = factory.CreateChannel();
}
private void button1_Click(object sender, EventArgs e)
{
double value = 0;
Double.TryParse(m_ValueTextBox.Text, out value);
m_Client.BeginGetSquareRoot(value, OnEndGetSquareRoot, null);
m_StartButton.Enabled = false;
m_ResultTextBox.Text = @"Loading...";
}
public void OnEndGetSquareRoot(IAsyncResult asyncResult)
{
this.Invoke(new MethodInvoker(delegate()
{
m_ResultTextBox.Text =
开发者_如何学编程 m_Client.EndGetSquareRoot(asyncResult).ToString();
m_StartButton.Enabled = true;
}));
}
}
The difference of described cases is only absence of declaration GetSquareRoot in IMyService interface.
I've seen that article before and it's just wrong. You're server side version of the IMyService
contract interface should not have the synchronous definition of the method at all. The WCF dispatcher runtime will always elect to map messages to a synchronous method definition over an asynchronous one. This is a situation where you would not share the raw .NET service contract interface with a client unless you also want to force the client to only ever be able to call the service asynchronously.
Also, remember, the fact that the client is using the async version of the method means absolutely nothing to the server side. It could be a Java service running on Linux on the other side of the wire for all the client knows. A client can always call either the sync or async version of the method, but it always looks the same to the service side.
You're calling different methods. The synchronous method is not implemented using the asynchronous methods.
精彩评论