WCF ChannelFactory asynchronous call
Asked Answered
K

1

7

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.

Kiger answered 23/6, 2013 at 18:0 Comment(4)
If you're on .Net 4.5, why aren't you using async-await?Eden
Maybe I am doing something wrong but when I tried execute two calls using asyns e.g. var t1 = await factory.CreateChannel().GetDataAsync(2); var t2 = await factory.CreateChannel().GetDataAsync(5); and each call was asynchronous but they were not performed simultaniously -> second request started after first was finished.Kiger
Well, that's because await doesn't change the order of execution. You need to call the first method and store its Task, call the second method and store its Task and only then await both.Eden
I knew that there have to be a way to mitigate this issue with async mentioned by me previousy, thanks. But the main question is still open, which option is better ?Kiger
E
4

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.

Eden answered 23/6, 2013 at 19:35 Comment(1)
Hi svick, I have a similar issue and was wondering if you could share the async equivalent. I am calling from a synchronous method but want to call multiple WCF services asynchronously. SO: https://mcmap.net/q/591737/-how-do-i-prevent-quot-maxing-out-quot-of-cpu-synchronous-method-calling-multiple-workers-asynchronously-amp-throttling-using-semaphoreslim/919426. If you answer with a sample for this question and an alternative that addresses my SO question, I will award you the bounty :)Yorkshire

© 2022 - 2024 — McMap. All rights reserved.