2

I would like to take advantage of the new task-based operations for a WCF client. I am currently using the WCFFacility as follows:

container.Register(Component
    .For<IAdminService>()
    .LifeStyle.Transient
    .AsWcfClient(new DefaultClientModel()
    {
        Endpoint = WCFHelpers.BasicHttp(settings.MaxReceivedMessageSize)
            .At(addr)
    }));

where IAdminService is the ServiceContract class. All the MSDN articles about task-based operations refer to setting a 'task based operations' tick box when importing the service reference. But in the style I am currently using, there is no imported service reference because I simple refer directly to the service contract interface.

So I am wondering how I can enable support for task-based operations with the least amount of changes to the current code.

[BTW - WCFHelpers is a utility class that generates a BindEndpointModel and addr is set up to an appropriate endpoint address prior to this code being executed]

samy
  • 14,832
  • 2
  • 54
  • 82
Terry Coatta
  • 595
  • 4
  • 14
  • Have you tried changing the methods in `IAdminService` to `Task`-returning ones? I think that should work. – svick Aug 18 '13 at 20:44
  • I have derived a new interface to add Task-returning methods. It only half works: The call makes it to the server but it seems the Task on the client never completes - it eventually times out. I cannot find a solution – Jack Ukleja Oct 16 '13 at 11:59

1 Answers1

2

The WCFFacility provides some extension methods that conform to the old async pattern. These can easily be converted to Tasks.

Try these extension methods:

public static class ClientExtensions
{
    public static async Task<TResult> CallAsync<TProxy, TResult>(this TProxy proxy, Func<TProxy, TResult> method)
    {
        return await Task.Factory.FromAsync(proxy.BeginWcfCall(method), ar => proxy.EndWcfCall<TResult>(ar));
    }

    public static async Task CallAsync<TProxy>(this TProxy proxy, Action<TProxy> method)
    {
        await Task.Factory.FromAsync(proxy.BeginWcfCall(method), ar => proxy.EndWcfCall(ar));
    }
}

In an async method they can be called like this:

// Func<T>
var result = await client.CallAsync(p => p.SayThisNumber(42));

// Action
await client.CallAsync(p => p.DoSomething());
Phil Degenhardt
  • 7,215
  • 3
  • 35
  • 46
  • 1
    do not await in the client extensions, just return the Task created from the Factory, then the consumer will await, wait or continue with another task, or whatever it is needed from the caller. Check here at the section "From APM to TAP" http://msdn.microsoft.com/en-us/library/hh873178(v=vs.110).aspx – Michael Denny Jun 02 '14 at 11:07