Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF ChannelFactory asynchronous call

I am playing with WCF and TPL Async library What I need is to be able request multiple WCF methods and wait untill all will be finished, so far I found that in .NET 4.5 there is very handy method Task.Factory.ContinueWhenAll which can be used to wait until all calls are finished

I found folowing ways to request WCF call in asynchronous way
Option 1. By using a proxy generated by "Add reference" dialog with option "Generate task-based operations" -> [e.g. here][1] - not an option in my case as we are using raw ChannelFactory
Option 2. By wrapping synchronous call in a task e.g.

    ChannelFactory<IService1> factory = new ChannelFactory<IService1>("BasicHttpBinding_IService1");  

        Task<string> t1 = Task<string>.Factory.StartNew(() => { return factory.CreateChannel().GetData(2); });
        Task<string> t2 = Task<string>.Factory.StartNew(() => { return factory.CreateChannel().GetData(5); });

        Task.Factory.ContinueWhenAll(new[] { t1, t2 }, t =>
        {
            foreach (var task in t)
            {
                //get result here
            }
        });

Option 3. By creating client side asynchronous version of contract interface e.g.

[ServiceContract(Namespace = "X", Name = "TheContract")]//Server side contract
public interface IService1
{
    [OperationContract]
    string GetData(int value);
}

[ServiceContract(Namespace = "X", Name = "TheContract")]//client side contract
public interface IService1Async
{
    [OperationContract]
    string GetData(int value);

    [OperationContract]
    Task<string> GetDataAsync(int value);
}

And having this I can invoke method asynchronously e.g.

 ChannelFactory<IService1Async> factory = new ChannelFactory<IService1Async>("BasicHttpBinding_IService2");

        var t1 = factory.CreateChannel().GetDataAsync(2);
        var t2 = factory.CreateChannel().GetDataAsync(5);

        Task.Factory.ContinueWhenAll(new[] { t1, t2 }, (Task<string>[] t) =>
            {
                foreach (var task in t)
                {
                    //get result here
                }
            });

So the question is as follows, what advantages has option 3 in comparison with option 2, is calling WCF methods as in Option 2 is correct ? Option 2 has one advantages in comparison with 3 namely there is no need to create client side contract interface.

like image 576
Krzysiek Avatar asked Jun 23 '13 18:06

Krzysiek


People also ask

How do you call async method in WCF?

To call a WCF service method asynchronously you need to create an AsyncCallback delegate and pass this delegate to the asynchronous proxy method. Note that the AsyncCallback delegate is executed on a worker thread and so this doesn't block the main thread of the application.

Is WCF asynchronous?

In Windows Communication Foundation (WCF) applications, a service operation can be implemented asynchronously or synchronously without dictating to the client how to call it. For example, asynchronous service operations can be called synchronously, and synchronous service operations can be called asynchronously.

How do you call operations asynchronously using a channel factory?

To access a service operation asynchronously, create the client and call the Begin[Operation] (for example, BeginAdd ) and specify a callback function, as shown in the following sample code. When the callback function executes, the client calls End<operation> (for example, EndAdd ) to retrieve the result.

What is ChannelFactory C#?

ChannelFactory class is used to construct a channel between the client and the service without the need of a proxy. In some cases, you may have a service that is tightly bound to the client application. In such a case, you can reference the Interface DLL directly and use ChannelFactory to call your methods using that.


1 Answers

In option #2, each invocation of GetData() will block a thread for the whole time the method executes. In option #3, while the GetDataAsync() operation is in progress, no thread is blocked by it.

This means that option #3 is more efficient and you should use the -Async version of the method if efficiency is important for you.

like image 79
svick Avatar answered Oct 05 '22 13:10

svick