2012-12-04 13 views
11

私はこの単純な方法があります:タスク<T>対して非同期の代理人はC#でですか?

Task<string> task = Task.Factory.StartNew<int> (() => Work ("lalala")); 
... 
int result = task.Result; 

またはこれに:

static int Work (string s) { return s.Length; } 

を私はそれを実行することができ

Func<string, int> method = Work; 
IAsyncResult myIasync= method.BeginInvoke ("lalala", null, null); 
... 
int result = method.EndInvoke (myIasync); 
  • 彼らの両方が、スレッドプールのスレッドを使用します。
  • 両方とも実行が完了するのを待つ(値を読むとき)
  • 両方とも、呼び出し元に例外を戻します。

いつそれぞれ使うべきですか?

+0

私はタスクがより新しいと思っていますが、この小さなコードとの違いはほとんどありません。 –

答えて

18

IAsyncResultを使用する2番目の形式は、かなり古いものであり、はるかに強力ではありません。 Task<T>は、.NET 4で導入されました。非同期操作を表すための好ましい方法です。 C#5では、非ブロッキングの方法でタスク(または他の非同期操作)を待つことができる「非同期関数」をサポートすることが特に簡単です。

BeginInvokeの代わりにTaskを使用すると、操作自体がどのように実行されるかはほとんど変わりませんが(スケジューリングなどの点でより多くのオプションがありますが)、コードの観点から大きな違いがあります結果を使用したり、複数のタスクを待ったり、失敗を処理したりするために、結果を使用したいと思っています。

C#5(.NET 4.5、または.NET 4プラス非同期ターゲティングパック)これは、非同期操作の管理に関して、あなたの人生をかなり容易にします。それは前進の方法です。

+0

ありがとうございます。タスクが実行に非常に時間がかかるとしましょう。スレッドプールスレッドが終了するまでスレッドスレッドを結び付けますか?(スレッドプールには[n-1]スレッドがあります)仕事がスレッドプール以外のスレッドに委譲され、完了したときにのみスレッドプールスレッドに戻ります... –

+1

@ AutoExec.Bat: 'Task'を使うと、長時間実行されているタスクであることが分かります。この場合、スレッドプール以外のスレッドが使用されます。 「スレッドプールスレッドに戻ってきた」という意味がはっきりしません。 *何がスレッドプールスレッドに戻るのでしょうか? –

+0

仕事をしなければなりません。それは長い仕事です。このジョブは、スレッドプールスレッド、**または**で実行できます**非スレッドプール**スレッドに転送することができます(スレッドは_back_をプールに追加して、他の要求をサーバーに送ります)。ジョブは(スレッドプール以外のスレッドで)終了します。_「完了しました」というメッセージが表示され、コントロールはスレッドプールスレッドに戻ります。 (アイデアは、スレッドプールのスレッドを無駄にしないようにすることです)。私の質問は:どのように_TaskとIAsync_はそのように動作するのですか...(実際のジョブはスレッドプールか非スレッドスレッドによって気になりますか?) –

0

タスクはより洗練されていて、もっと最近(.Net 4)導入されました。

関連する問題