Właśnie zobaczyłem 3 procedury dotyczące korzystania z TPL, które wykonują tę samą pracę; oto kod:
public static void Main()
{
Thread.CurrentThread.Name = "Main";
// Create a task and supply a user delegate by using a lambda expression.
Task taskA = new Task( () => Console.WriteLine("Hello from taskA."));
// Start the task.
taskA.Start();
// Output a message from the calling thread.
Console.WriteLine("Hello from thread '{0}'.",
Thread.CurrentThread.Name);
taskA.Wait();
}
public static void Main()
{
Thread.CurrentThread.Name = "Main";
// Define and run the task.
Task taskA = Task.Run( () => Console.WriteLine("Hello from taskA."));
// Output a message from the calling thread.
Console.WriteLine("Hello from thread '{0}'.",
Thread.CurrentThread.Name);
taskA.Wait();
}
public static void Main()
{
Thread.CurrentThread.Name = "Main";
// Better: Create and start the task in one operation.
Task taskA = Task.Factory.StartNew(() => Console.WriteLine("Hello from taskA."));
// Output a message from the calling thread.
Console.WriteLine("Hello from thread '{0}'.",
Thread.CurrentThread.Name);
taskA.Wait();
}
Ja po prostu nie rozumiem, dlaczego MS daje 3 różne sposoby uruchamiania zadań w OC, ponieważ wszystkie działają tak samo: Task.Start()
, Task.Run()
i Task.Factory.StartNew()
.
Powiedz mi, są Task.Start()
, Task.Run()
i Task.Factory.StartNew()
używane w tym samym celu lub mają one inne znaczenie?
Kiedy używać Task.Start()
, kiedy używać, Task.Run()
a kiedy używać Task.Factory.StartNew()
?
Proszę, pomóż mi szczegółowo zrozumieć ich rzeczywiste użycie zgodnie ze scenariuszem wraz z przykładami.
Task.Run
- może to odpowie na twoje pytanie;)Task.Start
jest rzeczywiście przydatne.Odpowiedzi:
Task.Run
jest skrótem dlaTask.Factory.StartNew
z określonymi bezpiecznymi argumentami:Został dodany w .Net 4.5, aby pomóc w coraz częstszym używaniu
async
i odciążaniu pracyThreadPool
.Task.Factory.StartNew
(dodane wraz z TPL w .Net 4.0) jest znacznie bardziej niezawodne. Powinieneś go używać tylko wtedy, gdyTask.Run
nie wystarczy, na przykład, gdy chcesz użyćTaskCreationOptions.LongRunning
(choć jest to niepotrzebne, gdy delegat jest asynchroniczny. Więcej na ten temat na moim blogu: LongRunning Is Useless For Task.Run With async-await ). Więcej na tematTask.Factory.StartNew
w Task.Run vs Task.Factory.StartNewNigdy nie twórz
Task
iStart()
nie dzwoń, chyba że znajdziesz do tego wyjątkowo dobry powód. Powinien być używany tylko wtedy, gdy masz część, która musi tworzyć zadania, ale nie planujesz ich, a inną część, która planuje bez tworzenia. To prawie nigdy nie jest odpowiednie i może być niebezpieczne. Więcej w „Task.Factory.StartNew” a „nowe zadanie (...). Start”Podsumowując, najczęściej używaj
Task.Run
,Task.Factory.StartNew
jeśli musisz i nigdy nie używajStart
.źródło
Task.Start
ma swoje miejsce głównie do dziedziczenia typów.Krótka odpowiedź :
Jeśli nie używasz zagnieżdżonych zadań podrzędnych i zawsze chcesz, aby Twoje zadania były wykonywane w puli wątków , lepiej jest użyć
Task.Run
.Długa odpowiedź:
Task.Run
iTask.Factory.StartNew
oba zapewniają obsługę tworzenia i planowania obiektów Task, więc nie musimy tworzyćTask
połączeń iStart()
Jest równa:
I
Jest równa:
Task.Run
używa,TaskCreationOptions.DenyChildAttach
co oznacza, że zadania dzieci nie mogą być dołączone do elementu nadrzędnego i używa,TaskScheduler.Default
co oznacza, że ten, który uruchamia zadania w puli wątków, będzie zawsze używany do uruchamiania zadań.Task.Factory.StartNew
używa,TaskScheduler.Current
co oznacza harmonogram bieżącego wątku, może być,TaskScheduler.Default
ale nie zawsze.źródło