2011-08-09 14 views
8

既存のAPI RestSharpを使用してTPLを使用したいので、継続を使用できます。既存の非同期APIでTPLを使用する

しかし、これは、古典的な.NETのアプローチを非同期に取らず、代わりにコールバックを実装するAPIをラップする必要があることを意味します。

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

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

ここで、可能であれば、ExecuteAsyncをTPLにラップしたいと思います。しかし私は私の人生のために、それをする方法を理解することはできません。

アイデア?

+0

TaskCompletionSourceはRestSharpで動作しましたか? –

+0

はい、そうでした。 (これが私が答えを受け入れた理由です) –

答えて

12

TPLは、タスクとしてほとんどすべてを公開できるようにするTaskCompletionSourceクラスを提供します。 SetResultまたはSetExceptionを呼び出すと、タスクの成功または失敗を引き起こすことができます。あなたの例では、おそらくのようなもの行うことができます:

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で指定されたデリゲートはスケジュールされ、タスクが完了した後に実行されます。あなたはあなたがそれをデリゲートの中で 'false'と見ていると言っていますか? –

+1

いいえ、問題は私が' .Start() 'と呼んでいたようです。 WP7用のMonoの実装は合法ではないと私に警告していませんでした(私には間違っていると私に言った.NET 4.0コンソールアプリでテストしました)。 –

1

これは私にとって大きな苦労点でした。 g TPLも同様です。

あなたが探しているのはTaskCompletionSourceです。 TaskCompletionSourceを作成すると、対応するTaskCompletionSourceSetResultまたはSetExceptionメソッドを呼び出すと完了する特殊なTaskオブジェクト(TaskCompletionSource.Taskプロパティでアクセス可能)が作成されます。

この投稿はhow to wrap APM operations with the TPL(およびRxも)について説明しています。 this gistも参照してください。これは、TPLでラップされたAPM操作を示しています。

関連する問題