Sdílet prostřednictvím


Plánovače úloh

Jsou představovány plánovače úloh System.Threading.Tasks.TaskScheduler Třída Plánovač úloh zajišťuje nakonec proveden práci úkolu. Výchozí Plánovač úloh je založena.NET Framework 4 zachovalo, který poskytuje krást práci pro vyrovnávání zatížení podprocesu vstřikování/vynětím maximální propustnost a celkově dobrý výkon. Mělo by být dostačující pro většinu scénářů. Ale pokud vyžadují zvláštní funkce, můžete vytvořit vlastní Plánovač a povolení pro určité úkoly nebo dotazy. Další informace o vytvoření a použití plánovače úloh, viz Postupy: Vytvoření plánovače úloh, které omezuje stupeň souběžnosti. Další příklady vlastní plánovače, viz Paralelních vzorků rozšíření na webu MSDN kód galerie.

Výchozí zachovalo a Plánovač úloh

Výchozí Plánovač úloh Knihovna paralelní a PLINQ použití.NET Framework ThreadPool do fronty a provedení práce. V .NET Framework 4, ThreadPool používá informace poskytované System.Threading.Tasks.Task typu paralelní úkoly efektivně podporují rovnoběžnosti uzamykání (existence krátkodobého jednotky práce) a dotazy často představují.

Globální fronty zachovalo vs.Místní fronty

Jako v předchozích verzích.NET Framework ThreadPool udržuje globální FIFO (first-in, budou) pracovní fronty podprocesy v každé doméně aplikace. Pokud program zavolá QueueUserWorkItem (nebo UnsafeQueueUserWorkItem), práce na této sdílené fronty a nakonec další podproces, který je k dispozici na de-queued. V .NET Framework 4, tato fronta byla vylepšena uvolnit zámek algoritmus, který se podobá použití ConcurrentQueue třídy. Pomocí této implementace uvolnit zámek ThreadPool stráví méně času, kdy fronty a de-queues pracovní položky. Tato výhoda je k dispozici pro všechny programy, které používají ThreadPool.

Úkoly nejvyšší úrovně, které jsou úkoly, které jsou vytvořeny v kontextu jiného úkolu, jsou uváděny na globální fronty stejně jako libovolné jiné položky. Však vnořené nebo podřízené úkoly, které jsou vytvořeny v kontextu jiného úkolu, jsou zpracovány docela jinak. Dítě nebo vnořené úkolu je do místní fronty specifická podprocesu je spuštěn nadřazený úkol. Nadřazený úkol může být úkol nejvyšší úrovně nebo také může být podřízený jinému úkolu. Když tento podproces připraven pro další práci, nejprve hledá v místní fronta. Pokud tam čeká pracovní položky, lze k nim rychle. Místní fronty jsou přístupné poslední v, budou objednávky (LIFO) za účelem zachování lokality mezipaměti a snížit tvrzení. Další informace o podřízené úkoly a úkoly vnořené naleznete Vnořené a podřízené úlohy.

Následující příklad ukazuje některé úkoly, které jsou naplánovány na globální fronty a jiné úlohy naplánované na místní fronta.

Sub QueueTasks()

    ' TaskA is a top level task.
    Dim taskA = Task.Factory.StartNew(Sub()

                                          Console.WriteLine("I was enqueued on the thread pool's global queue.")

                                          ' TaskB is a nested task and TaskC is a child task. Both go to local queue.
                                          Dim taskB = New Task(Sub() Console.WriteLine("I was enqueued on the local queue."))
                                          Dim taskC = New Task(Sub() Console.WriteLine("I was enqueued on the local queue, too."),
                                                                  TaskCreationOptions.AttachedToParent)

                                          taskB.Start()
                                          taskC.Start()

                                      End Sub)
End Sub
void QueueTasks()
{
    // TaskA is a top level task.
    Task taskA = Task.Factory.StartNew( () =>
    {                
        Console.WriteLine("I was enqueued on the thread pool's global queue."); 

        // TaskB is a nested task and TaskC is a child task. Both go to local queue.
        Task taskB = new Task( ()=> Console.WriteLine("I was enqueued on the local queue."));
        Task taskC = new Task(() => Console.WriteLine("I was enqueued on the local queue, too."),
                                TaskCreationOptions.AttachedToParent);

        taskB.Start();
        taskC.Start();

    });
}

Použití místních front nejen snižuje tlak na globální fronty, také využívá výhod dat lokality. Fronty pracovních položek v místním často referenční datové struktury, které jsou fyzicky blízko k sobě v paměti. V těchto případech data již v mezipaměti po spuštění první úkol a rychle přistupovat. Oba Paralelní LINQ (PLINQ) a Parallel třídy rozsáhlé, použijte vnořené úkoly a podřízené úkoly a dosáhnout významného speedups pomocí místní pracovní fronty.

Krádež práce

.NET Framework 4 ThreadPool Také mají funkce práce krást algoritmus k žádné podprocesy sedí nečinnosti, zatímco jiné stále pracovat v jejich fronty. Když je připravena k další pracovní podproces fondu podprocesů, nejprve hledá v čele místní fronty, pak v globální fronty a potom v místní fronty jiných podprocesů. Pokud najde pracovní položky do místní fronty jiným podprocesem, nejprve použije heuristické Ujistěte se, že ji spustit práci efektivně. Pokud je to možné, de-queues pracovní položka zadní (v pořadí FIFO). To snižuje tvrzení na každé místní fronty a zachová data lokality. Tato architektura umožňuje .NET Framework 4 ThreadPool vyrovnání zatížení pracovat efektivněji než minulých verzí.

Dlouhotrvající úkoly

Můžete explicitně zabránit úlohy právě do místní fronty. Může například víte, že konkrétní pracovní položky spustí poměrně dlouhou dobu a pravděpodobně blokovat další položky práce na místní fronta. V takovém případě můžete zadat LongRunning možnost, která poskytuje nápovědu pro Plánovač, další podproces může být vyžadováno pro úkol tak, aby jej neblokuje dopředu průběh jiné podprocesy nebo pracovních položek na místní fronty. Pomocí této možnosti vyhnete ThreadPool kompletně, včetně na globální a místní fronty.

Inlining úloh

V některých případech při úkolu je očekáván, ji mohou být spouštěny synchronně podproces, který provádí operace čekání. To zvyšuje výkon, jako zabraňuje potřebu další podproces využitím existující vlákno, které by jste blokovali, jinak. Chcete-li zabránit chybám, kvůli re-entrancy úkolu inlining dochází pouze nalezený cíl čekání podprocesu příslušné místní fronty.

Určení kontextu synchronizace

Můžete použít TaskScheduler.FromCurrentSynchronizationContext metody určíte, že úkol naplánovat na konkrétní vlákno. To je užitečné v rámcích jako model Windows Forms a kde přístup k rozhraní objektů uživatele je často omezen na kód, který běží ve stejném podprocesu vytvoření objektu UI Windows Presentation Foundation. Další informace naleznete v tématu Postupy: Plán práce na zadané synchronizační kontext.

Viz také

Odkaz

TaskScheduler

Koncepty

Knihovna paralelních úloh

Postupy: Plán práce na zadané synchronizační kontext

Další zdroje

Postupy: Vytvoření plánovače úloh, které omezuje stupeň souběžnosti

Továrny úloh