Udostępnij przez


Omówienie planowania

Dwie formy planowania w programie Orleans są istotne dla ziarna:

  1. Planowanie żądań: Planowanie przychodzących wywołań zadań do wykonania zgodnie z regułami omówionymi w Request scheduling.
  2. Planowanie zadań: Planowanie synchronicznych bloków kodu do wykonania w sposób jednowątkowy.

Cały kod ziarna jest wykonywany w harmonogramie zadań ziarna, co oznacza, że żądania są również wykonywane w harmonogramie zadań ziarna. Nawet jeśli reguły planowania żądań zezwalają na współbieżne wykonywanie wielu żądań, nie będą one wykonywane równolegle , ponieważ harmonogram zadań ziarna zawsze wykonuje zadania jeden po drugim i nigdy nie wykonuje wielu zadań równolegle.

Planowanie zadań

Aby lepiej zrozumieć planowanie, rozważ następujące ziarno: MyGrain. Ma metodę o nazwie DelayExecution() , która rejestruje komunikat, czeka trochę czasu, a następnie rejestruje kolejny komunikat przed zwróceniem.

public interface IMyGrain : IGrain
{
    Task DelayExecution();
}

public class MyGrain : Grain, IMyGrain
{
    private readonly ILogger<MyGrain> _logger;

    public MyGrain(ILogger<MyGrain> logger) => _logger = logger;

    public async Task DelayExecution()
    {
        _logger.LogInformation("Executing first task");

        await Task.Delay(1_000);

        _logger.LogInformation("Executing second task");
    }
}

Po wykonaniu tej metody treść metody jest wykonywana w dwóch częściach:

  1. Pierwsze _logger.LogInformation(...) wywołanie i wywołanie Task.Delay(1_000).
  2. Drugie _logger.LogInformation(...) wywołanie.

Drugie zadanie nie jest zaplanowane w harmonogramie zadań ziarna do momentu Task.Delay(1_000) zakończenia wywołania. W tym momencie planuje kontynuację metody ziarna.

Oto graficzna reprezentacja sposobu planowania i wykonywania żądania jako dwóch zadań:

Przykład wykonania żądania opartego na dwóch zadaniach.

Powyższy opis nie jest specyficzny dla Orleanselementu ; opisuje sposób działania planowania zadań na platformie .NET. Kompilator języka C# konwertuje metody asynchroniczne na maszynę stanu asynchronicznego, a wykonywanie jest wykonywane przez tę maszynę stanu w dyskretnych krokach. Każdy krok jest harmonogramem bieżącego TaskScheduler (dostępnego za pośrednictwem TaskScheduler.Current, domyślnie ) TaskScheduler.Defaultlub bieżącego SynchronizationContext. Jeśli używany jest TaskScheduler, każdy krok w metodzie reprezentuje wystąpienie Task, które jest przekazywane do tego TaskScheduler. W związku z tym Task w platformie .NET może reprezentować dwa pojęcia.

  1. Operacja asynchroniczna, którą można oczekiwać. Wykonanie powyższej DelayExecution() metody jest reprezentowane przez element Task , którego można oczekiwać.
  2. Synchroniczny blok pracy. Każdy etap w powyższej metodzie DelayExecution() jest reprezentowany przez Task.

Gdy używany jest TaskScheduler.Default, kontynuacje planują się bezpośrednio na platformie .NET ThreadPool i nie są owinięte w obiekt Task. Zawijanie ciągów w Task wystąpieniach odbywa się przejrzyście, więc programiści rzadko muszą być świadomi tych szczegółów implementacji.

Planowanie zadań w programie Orleans

Każda aktywacja ziarna ma własne TaskScheduler wystąpienie odpowiedzialne za wymuszanie modelu jednowątkowego wykonywania ziarna. Wewnętrznie jest to TaskScheduler implementowane za pośrednictwem metod ActivationTaskScheduler i WorkItemGroup. WorkItemGroup przechowuje zadania w kolejce w obiekcie Queue<T> (gdzie T jest wewnętrznie Task) i implementuje IThreadPoolWorkItem. Aby wykonać każdą aktualnie w kolejce Task, WorkItemGroup harmonogramuje się sam na .NET ThreadPool. Gdy platforma .NET ThreadPool wywołuje metodę WorkItemGroup dla IThreadPoolWorkItem.Execute(), WorkItemGroup wykonuje zakolejkowane wystąpienia Task jedno po drugim.

Każde ziarno ma harmonogram, który wykonuje się przez zaplanowanie na platformie .NET ThreadPool:

Orleans jednostki przypisujące się w puli wątków platformy .NET.

Każdy harmonogram zawiera kolejkę zadań:

Kolejka harmonogramu zaplanowanych zadań.

Platforma .NET ThreadPool wykonuje każdy element roboczy umieszczony w kolejce. Obejmuje to grain schedulers, a także inne elementy robocze, takie jak te zaplanowane za pomocą Task.Run(...).

Wizualizacja wszystkich harmonogramów uruchomionych w puli wątków platformy .NET.

Uwaga

Harmonogram ziarna może być wykonywany tylko w jednym wątku jednocześnie, ale nie zawsze jest wykonywany w tym samym wątku. Platforma .NET ThreadPool może używać innego wątku za każdym razem, gdy wykonywany jest harmonogram ziarna. Harmonogram ziarna zapewnia, że wykonuje tylko jeden wątek w danym momencie, implementuje model wykonywania pojedynczego wątku ziarna.