Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using TPL with existing async APIs

I want to use TPL with a existing API, RestSharp to be specific, so I can use continuations.

But this means I have to wrap a API that doesn't take the classical .NET approach to async, but instead implements callbacks. Take some code like this:

var client = new RestClient("service-url");
var request = new RestRequest();

client.ExecuteAsync<List<LiveTileWeatherResponse>>(request, 
    (response) =>
    {
        ...
    });

So here I want to wrap the ExecuteAsync in TPL, if it's possible. But I can't for the life of me, figure out how to do it.

Any ideas?

like image 930
Claus Jørgensen Avatar asked Aug 09 '11 00:08

Claus Jørgensen


People also ask

Is async await part of TPL?

Await & Async was built on the Task Parallel Library (TPL) which was introduced in the . NET Framework 4. Their purpose is to enable asynchronous programming.

Which one of the following is possible using TPL?

By using TPL, you can maximize the performance of your code while focusing on the work that your program is designed to accomplish. In . NET Framework 4, the TPL is the preferred way to write multithreaded and parallel code.

How are threads different from TPL?

Compared to the classic threading model in . NET, Task Parallel Library minimizes the complexity of using threads and provides an abstraction through a set of APIs that help developers focus more on the application program instead of focusing on how the threads will be provisioned.

What is TPL in C#?

Task Parallel Library (TPL), basically provides a higher level of abstraction. Fundamentally, it boils down to a “task” which is equivalent to a thread except that it is more lightweight and comes without the overhead of creating an OS thread.


1 Answers

TPL provides TaskCompletionSource class which allows you to expose pretty much anything as a Task. By calling SetResult or SetException, you can cause the task to succeed or fail. In your example, you could probably do something like:

static Task<T> ExecuteTask<T>(this RestClient client, RestRequest request)
{
    var tcs = new TaskCompletionSource<T>();
    client.ExecuteAsync<T>(request, response => tcs.SetResult(response));
    return tcs.Task;
}

You can then use it:

var task = client.ExecuteTask<List<LiveTileWeatherResponse>>(request);
foreach (var tile in task.Result)
{}

Or, if you want to chain tasks:

var task = client.ExecuteTask<List<LiveTileWeatherResponse>>(request);
task.ContinueWith(
    t => 
    {
        foreach (var tile in t.Result)
        {}
    }
);

You can read more about TaskCompletionSource at http://blogs.msdn.com/b/pfxteam/archive/2009/06/02/9685804.aspx

like image 153
Bojan Resnik Avatar answered Oct 05 '22 02:10

Bojan Resnik