2016-07-17 6 views
53

Ich habe Methode:Was ist der Unterschied zwischen Task.Run ist() und 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"); 
} 

Und ich mag diese Methode in einer neuen Aufgabe beginnen. Ich kann neue Aufgabe beginnen wie diese

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

oder diese

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

Aber gibt es einen Unterschied zwischen Task.Run() und Task.Factory.StartNew(). Beide verwenden ThreadPool und starten Method() sofort nach dem Erstellen der Instanz der Aufgabe. Wann sollten wir die erste Variante verwenden und wann die zweite?

+1

Eigentlich muss StartNew den ThreadPool nicht verwenden, siehe den Blog, mit dem ich in meiner Antwort verlinkt bin. Das Problem ist 'StartNew', das standardmäßig' TaskScheduler.Current' verwendet, was möglicherweise der Thread-Pool ist, aber auch der UI-Thread. –

+0

Mögliches Duplikat von [Betreffend die Verwendung von Task.Start(), Task.Run() und Task.Factory.StartNew()] (https://stackoverflow.com/questions/29693362/regarding-usage-of-task-start -task-run-and-task-factory-startneu) –

Antwort

6

Die zweite wurde in neueren .NET-Framework-Version eingeführt und es ist recommended. Die erste größere Auswahl hat, ist der zweite eine Abkürzung:

Die Run-Methode bietet eine Reihe von Überlastungen, die es einfach, indem Sie die Standardwerte eine Aufgabe zu starten. Es ist eine leichte Alternative zu den StartNew Überladungen.

Und Stenografie meine ich eine technische shortcut:

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

Die zweite Methode, Task.Run hat in einer späteren Version des .NET-Framework (in .NET 4.5) eingeführt.

Die erste Methode, Task.Factory.StartNew, gibt Ihnen jedoch die Möglichkeit, eine Menge nützlicher Dinge über den Thread zu definieren, den Sie erstellen möchten, während Task.Run dies nicht bietet.

Zum Beispiel sagen wir, dass Sie einen lang laufenden Task-Thread erstellen möchten. Wenn ein Thread des Thread-Pools für diese Aufgabe verwendet wird, könnte dies als Missbrauch des Thread-Pools angesehen werden.

Eine Sache, die Sie tun könnten, um dies zu vermeiden, wäre, die Aufgabe in einem separaten Thread auszuführen. Ein neu erstellter Thread , der dieser Aufgabe zugewiesen wurde und nach Abschluss der Aufgabe zerstört würde. Sie kann dies mit dem Task.Run nicht erreichen, während Sie dies mit der Task.Factory.StartNew tun können, wie unten:

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

Wie es here heißt:

Also, in .NET Framework 4.5 Developer Preview haben wir die neue Task.Run-Methode eingeführt. Diese in keine Weise obsoleten Task.Factory.StartNew, sondern einfach gedacht als eine schnelle Möglichkeit sollte Task.Factory.StartNew , ohne zu verwenden, um ein Bündel von Parametern angeben. Es ist eine Abkürzung. Tatsächlich ist Task.Run tatsächlich implementiert in Bezug auf die gleiche Logik für Task.Factory.StartNew, nur einige Standardparameter übergeben. Wenn Sie eine Aktion an Task übergeben.Run:

Task.Run(someAction); 

, die genau äquivalent ist zu:

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

Ich habe ein Stück Code, wo die Statemente 'das entspricht genau 'nicht gilt. – Emaborsa

+1

@Emaborsa Ich würde mich freuen, wenn Sie dieses Stück Code veröffentlichen und Ihr Argument ausarbeiten könnten. Danke im Voraus ! – Christos

+0

Sie sind 40 loc mit einigen Abhängigkeiten ... wie mache ich das? – Emaborsa

14

Siehe this blog article, die den Unterschied beschreibt. Im Grunde tun:

Task.Run(A) 

ist die gleiche wie zu tun:

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

In meiner Anwendung, die zwei Dienste aufruft, verglich ich sowohl Task.Run und Task.Factory.StartNew. Ich fand, dass in meinem Fall beide gut funktionieren. Der zweite ist jedoch schneller.