2016-07-17 18 views
53

私は方法があります:Task.Run()とTask.Factory.StartNew(の違いは何ですか)

private static void Method() 
{ 
    Console.WriteLine("Method() started"); 

    for (var i = 0; i < 20; i++) 
    { 
     Console.WriteLine("Method() Counter = " + i); 
     Thread.Sleep(500); 
    } 

    Console.WriteLine("Method() finished"); 
} 

をそして私は新しいタスクにこの方法を開始します。 私はこの

var task = Task.Factory.StartNew(new Action(Method)); 

またはこの

var task = Task.Run(new Action(Method)); 

のような新しいタスクを開始することができます。しかしTask.Run()Task.Factory.StartNew()の間に違いがあります。どちらもThreadPoolを使い、Taskのインスタンスを作成した直後にMethod()を起動します。最初の変種を使うべきときと、2番目の変種を使うべきときは?

+1

実際、StartNewはThreadPoolを使用する必要はありません。私の答えにリンクしているブログを参照してください。問題は 'StartNew'で、デフォルトでは' TaskScheduler.Current'が使用されます。これはスレッドプールでもUIスレッドであってもかまいません。 –

+0

[Task.Start()、Task.Run()およびTask.Factory.StartNew()の使用については複製可能です(https://stackoverflow.com/questions/29693362/regarding-usage-of-task-start) –

答えて

6

新しい.NETフレームワークのバージョンで2番目に導入されたのはrecommendedです。最初は、より多くのオプションを持っている、第二の速記です:

Runメソッドは、デフォルト値を使用して にタスクを開始することが簡単にオーバーロードのセットを提供します。これは、 StartNewオーバーロードの軽量代替品です。

そして速記で、私は技術的なshortcutを意味:

public static Task Run(Action action) 
{ 
    return Task.InternalStartNew(null, action, null, default(CancellationToken), TaskScheduler.Default, 
     TaskCreationOptions.DenyChildAttach, InternalTaskOptions.None, ref stackMark); 
} 
62

第二の方法、Task.Run、(.NET 4.5で).NETフレームワークの新しいバージョンで導入されました。

ただし、最初のメソッドTask.Factory.StartNewは、作成するスレッドに関する多くの有益なものを定義する機会を与えますが、Task.Runはこれを提供しません。

たとえば、長時間実行しているタスクスレッドを作成するとします。スレッドプールのスレッドがこのタスクに使用される場合、これはスレッドプールの乱用と見なすことができます。

これを避けるためにできることは、別のスレッドでタスクを実行することです。新しく作成されたスレッドは、このタスクに専念し、タスクが完了すると破棄されます。あなたは以下のように、Task.Factory.StartNewでそうすることができますがあなたは、Task.Runでこれを達成することはできません。

Task.Factory.StartNew(..., TaskCreationOptions.LongRunning); 

それがhere記載されているとおり:

をので、.NET Frameworkの4.5で開発者プレビューでは、新しいTask.Runメソッド が導入されました。決してこれは Task.Factory.StartNew、 を廃止ではなく、単に パラメータの束を指定しなくても Task.Factory.StartNew を使用する簡単な方法として考えるべきです。それはショートカットです。実際、Task.Runは実際には であり、Task.Factory.StartNewで使用されているのと同じロジックで実装されています。 はデフォルトパラメータを渡すだけです。アクションを タスクに渡すとき。ファイル名を指定して実行:

Task.Run(someAction); 

とまったく同じです:

Task.Factory.StartNew(someAction, 
    CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); 
+3

私は「それと全く同じです」というステートメントが成立しないコードを持っています。 – Emaborsa

+1

@Emaborsaあなたがこのコードを投稿してあなたの議論を具体化できるのであれば、私は感謝します。前もって感謝します ! – Christos

+0

彼らはいくつかの依存関係を持つ40のlocです...どうすればいいですか? – Emaborsa

14

参照this blog article違いを説明しています。基本的にやって:私はTask.RunとTask.Factory.StartNewの両方を比較して、2つのサービスを呼び出し、自分のアプリケーションで

Task.Factory.StartNew(A, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); 
-3

を:

Task.Run(A) 

ことはやってと同じです。私は私の場合、両方とも正常に動作することがわかった。ただし、2番目の方が高速です。

関連する問題