Drake
Drake

Reputation: 2703

Wrap a function as an async task

I have a function that I would like to wrap so that I can use the async/await pattern:

wcfClientService.GetSomeString(parameter);

It's a call from a WCF client that I'm trying to make asynchronous, but that's not important (I know WCF supports async, but let's assume we don't have access to the WCF code).

I'm trying to wrap the method with the Task<T>.Factory.FromAsync method, but can't seem to get it right:

private Task<string> WrapWcfServiceAsyncTask(uint parameter)
{
    Func<uint, string> func = i => { return wcfClientService.GetSomeString(parameter); };

    var t = Task<string>.Factory.FromAsync(
                                           // What goes here?
                                          );
    return t;
}

Or even better, can someone write a method that takes a method as a parameter, and wraps and returns a Task<T> for it?

Upvotes: 6

Views: 15110

Answers (2)

i3arnon
i3arnon

Reputation: 116518

What you're trying to do is async over sync. You have a synchronous operation and you want to pretend it's asynchronous .

You can do that with Task.Run:

var result = await Task.Run(() => wcfClientService.GetSomeString(parameter));

but it's pointless as you're just offloading work from one ThreadPool thread to another.

If you want an asynchronous operation it needs to be asynchronous to begin with in some way, either with async-await or Begin/End, etc.

If you had BeginGetSomeString/EndSomeString which is already asynchronous you could have used FromAsync to turn it into async-await.

Upvotes: 13

Stephen Cleary
Stephen Cleary

Reputation: 456332

If you re-generate your WCF proxy with a modern version of Visual Studio, it should generate task-returning asynchronous methods by default. Note that the WCF service does not have to change at all; it is only the client proxy that needs to be updated.

Then you can call its methods with a plain await; there's no need for Task.Run:

private async Task<string> WrapWcfServiceAsyncTask(uint parameter)
{
  return await wcfClientService.GetSomeStringAsync(parameter);
}

Upvotes: 4

Related Questions