1

Async CTP is very nice to use. I saw some examples for windows phone, all using:
(Assembly AsyncCtpLibrary_Phone.dll, v2.0.50727, AsyncCtpExtensions).

 var client = new WebClient();
 string data = await client.DownloadStringTaskAsync(new Uri(url));

or something like the above code.

How can I use methods with async / await for my services? (WCF)
Today all methods work this way:

  service.MyRequestCompleted += service_myRequestCompleted;
  service.MyRequestAsync();

I can not find a way to use extension methods for services.

J. Lennon
  • 3,311
  • 4
  • 33
  • 64
  • I found this GREAT article on waiting for async functions. Works like a charm, and is really afficient. Take a look at this article: http://blogs.msdn.com/b/ptorr/archive/2011/07/12/background-agents-part-2-of-3.aspx Download code here: [http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-18-51-05/BackgroundAgentDemo.zip](http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-18-51-05/BackgroundAgentDemo.zip) – Christopher W. Brandsdal Jan 07 '13 at 20:15

2 Answers2

4

Unfortunetly, I haven't found a good way to generalize this for any event, but it's easy enough to adapt this for a particular event:

public static Task WhenRequestCompleted(MyService service) //can make it an extension method if you want.
{
    TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();

    service.MyRequestCompleted += () => //change parameter list to fit the event's delegate
        {
            tcs.SetResult(null);
        };
    service.MyRequestAsync();

    return tcs.Task;
}

Then you can do:

await WhenRequestCompleted(service);
//code that runs after the request is completed.

I assume you see the pattern here, so you could adapt this so that it would work with some other event on some other type.

Oh, and if the event has arguments that are particularly important to you then you could make this return a Task<T> instead of a Task and instead of using tcs.SetResult(null) you could use one of the parameters of the lambda to set the result.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • Argh, beat me to it, was just typing up the same approach using TaskCompletionSource. I wonder if this is how they backfilled many of the older .Net API's to support Task. – BFree Oct 12 '12 at 18:15
  • looks good, but is torture have q specify the event =( there is some other way, perhaps? – J. Lennon Oct 12 '12 at 18:52
  • What do you expect to write? I can't see how you could do much less than what's here. – Servy Oct 12 '12 at 18:56
  • perhaps using generic, reflection, expression trees? although this could become slow. To try to have a single method for the entire service. – J. Lennon Oct 12 '12 at 19:27
  • 1
    @J.Lennon [Related link](http://stackoverflow.com/q/12865848/1159478). I tried to do this a while ago and have yet to succeed. – Servy Oct 12 '12 at 19:37
0

It's been a while since I've worked on WP7, so I'm going to assume that the client proxy has both EAP endpoints (*Async + *Completed) and APM endpoints (Begin* + End*) for each contract method.

If that's correct, then you can use TaskFactory.FromAsync to wrap the Begin* / End* methods, as such:

[ServiceContract]
public interface ICalculator
{
  [OperationContract]
  uint Divide(uint numerator, uint denominator);
}

static class Program
{
  // Wrap those Begin/End methods into a Task-based API.
  public static Task<uint> DivideAsyncTask(this CalculatorClient client,
      uint numerator, uint denominator)
  {
    return Task<uint>.Factory.FromAsync(client.BeginDivide, client.EndDivide,
        numerator, denominator, null);
  }

  static async Task CallCalculator()
  {
    var proxy = new CalculatorClient();
    var task = proxy.DivideAsyncTask(10, 5);
    var result = await task;
    Console.WriteLine("Result: " + result);
  }

  static void Main(string[] args)
  {
    try
    {
      CallCalculator().Wait();
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
    }

    Console.ReadKey();
  }
}

You may be interested in one of my blog posts async WCF today and tomorrow - unfortunately, WP7 is still stuck in "today" mode. The Async CTP will probably be abandoned shortly now that VS2012 is out.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • I tried something like this but it is not possible to do for WP7. Methods (Begin/End) do not exist by default and you can not use ChannelFactory. – J. Lennon Oct 14 '12 at 21:57