开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜