2011-08-09 40 views
8

我想使用TPL与现有的API,RestSharp是特定的,所以我可以使用continuation。使用TPL与现有的异步API

但这意味着我必须换不走传统的.NET方法异步API一个,而是实现了回调。采取这样的代码:

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

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

所以这里我想包装在TPL ExecuteAsync,如果可能的话。但我不能为了我的生活,找出如何去做。

任何想法?

+0

TaskCompletionSource是否与RestSharp兼容? –

+0

是的,它的确如此。 (这就是我接受答案的原因) –

回答

12

TPL提供TaskCompletionSource类,它可以让你暴露几乎任何一个任务。通过调用SetResultSetException,可以使任务成功或失败。在你的榜样,你也许可以这样做:

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; 
} 

然后,您可以使用它:

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

或者,如果你想链任务:

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

你可以阅读更多关于TaskCompletionSource在http://blogs.msdn.com/b/pfxteam/archive/2009/06/02/9685804.aspx

+0

这绝对是正确的方法。但遗憾的是,ContinueWith被提前调用,'t.IsCompleted'被设置为'false':( –

+0

这并不重要 - 在ContinueWith中指定的委托将在任务完成后进行调度和执行,无论何时可能。 t.IsCompleted应该总是在委托内部是'真实'的,尽管......你是说你在委托内部看到它是'false'吗? –

+1

不,这个问题似乎是我调用'.Start()',和WP7的单声道实现,没有*警告我,这是不合法的(我用.NET 4.0控制台应用程序测试过,它告诉我这是错误的) –

1

learnin时,这是一个重大的痛点对我来说g TPL也是如此。

你要寻找的是TaskCompletionSource。当你创建一个TaskCompletionSource,它创建了一个特殊Task对象(由TaskCompletionSource.Task属性访问),这只有当你调用相关TaskCompletionSourceSetResultSetException方法完成。

这篇文章解释how to wrap APM operations with the TPL(也Rx)的。另请参阅this gist演示包装在TPL中的APM操作。