True Asynchronous WCF Service

I am running an asynchronous service. After evaluating Microsoft's example , I wonder if their approach is really asynchronous. I am sure that it is, but some of the samples that I saw online and the AsyncCallback parameter make me wonder.

In accordance with this example, we need to implement a couple of Begin and End methods:

 public IAsyncResult BeginGetAcmeAnvil(AsyncCallback callback, object state) { // Starts synchronous task var acmeAsyncResult = new AcmeAsyncResult<Anvil> { Data = new Anvil() }; return acmeAsyncResult; } public Anvil EndGetAcmeAnvil(IAsyncResult result) { var acmeAsyncResult = result as AcmeAsyncResult<Anvil>; return acmeAsyncResult != null ? acmeAsyncResult.Data : new Anvil(); } 

Pretty simple, but why do we have an AsyncCallback parameter? Shouldn't we call a callback , which in turn will call the End method?

Here is what I mean:

 public delegate void AsyncMethodCaller(AcmeAsyncResult<Anvil> acmeAsyncResult, AsyncCallback callback); public IAsyncResult BeginGetAcmeAnvil(AsyncCallback callback, object state) { var acmeAsyncResult = new AcmeAsyncResult<Anvil>(); var asyncMethodCaller = new AsyncMethodCaller(GetAnvilAsync); // Starts asynchronous task asyncMethodCaller.BeginInvoke(acmeAsyncResult, callback, null, null); return acmeAsyncResult; } private void GetAcmeAnvilAsync(AcmeAsyncResult<Anvil> acmeAsyncResult, AsyncCallback callback) { acmeAsyncResult.Data = new Anvil(); callback(acmeAsyncResult); // Triggers EndGetAcmeAnvil } public Anvil EndGetAcmeAnvil(IAsyncResult result) { var acmeAsyncResult = result as AcmeAsyncResult<Anvil>; return acmeAsyncResult != null ? acmeAsyncResult.Data : new Anvil(); } 

I did some load testing using loadUI , but there were no obvious changes in performance.

+8
c # asynchronous wcf
source share
2 answers

I found a good article that explains how to get the best performance from your Async WCF service.

The bottom line is this:

  • do not do the hard work in the Get started method and
  • make a callback to start the End method.

Here is an excerpt from the text:

For maximum performance, you should use two principles when you invoke / implement the asynchronous pattern described above:

  • Principle 1: Do Not Do Hard Work Inside the Start ... Method

    The reason for this is that you must return the calling thread as soon as possible so that the caller can schedule another job. If its a user interface thread, the application should use the thread to respond to user inputs. You should always put heavy operations in a different thread, if possible.

  • Principle 2: Avoid calling the End method on the same Begin method thread.

    The End method is usually blocked. He is waiting for the operation to complete. If you implement the End method, you will see that it actually calls IAsyncResult.WaitHandle.WaitOne () . On the other hand, as a normal implementation, this WaitHandle is the delay allocated by ManualResetEvent . Until you name it, it will not be highlighted at all. For quick operations, it's pretty cheap. However, as soon as the End is called, you will have to select it. The right place to call End is a callback call. When a callback is called, it means that the lock operation is indeed complete. At this point, you can call Finish to retrieve the extracted data without sacrificing performance.

+5
source share

I think the main reason it is split is because the WCF runtime handles thread synchronization rather than a handle manually.

If you called the end method through a callback, you would have to handle the synchronization, which makes the template quite complex (as you can see in the encoding examples). The purpose of this template is not that you really know about the streaming material, you just want to encode your long-running operation without worrying about the details of the streaming implementation.

+2
source share

All Articles