Aracılığıyla paylaş


Zamanlamaya genel bakış

içinde Orleans zamanlamanın iki biçimi tahıllarla ilgilidir:

  1. İstek zamanlama: İstek zamanlama bölümünde belirtilen kurallara göre, gelen grain çağrılarını yürütme amacıyla zamanlama.
  2. Görev zamanlama: Zaman uyumlu kod bloklarının tek iş parçacıklı şekilde yürütülmesini planlama.

Tüm tahıl kodu, tahılın görev zamanlayıcısında yürütülür, yani istekler de tahılın görev zamanlayıcısında yürütülür. İstek zamanlama kuralları birden çok isteğin eşzamanlı olarak yürütülmesine izin verse bile, bunlar paralel olarak yürütülemez çünkü tahılın görev zamanlayıcısı görevleri her zaman birer birer yürütür ve hiçbir zaman birden çok görevi paralel olarak yürütmez.

Görev zamanlama

Zamanlamayı daha iyi anlamak için aşağıdaki tahılı MyGraingöz önünde bulundurun: . Bir iletiyi günlüğe kaydeden, bir süre bekleyen ve sonra geri dönmeden önce başka bir iletiyi günlüğe kaydeden adlı DelayExecution() bir yöntemi vardır.

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");
    }
}

Bu yöntem yürütüldüğünde, yöntemin gövdesi iki ayrı bölümde çalışır.

  1. İlk _logger.LogInformation(...) çağrısı ve Task.Delay(1_000)'e çağrı.
  2. İkinci _logger.LogInformation(...) çağrı.

Çağrı Task.Delay(1_000) tamamlanmadan, ikinci görev tahıl görev zamanlayıcısında zamanlanmaz. Bu noktada, işlem yönteminin devamını planlar.

bir isteğin iki görev olarak zamanlanıp yürütülme şeklinin grafik gösterimi aşağıdadır:

İki görev tabanlı istek yürütme örneği.

Yukarıdaki açıklama öğesine Orleansözgü değildir; .NET'te görev zamanlamanın nasıl çalıştığını açıklar. C# derleyicisi zaman uyumsuz yöntemleri zaman uyumsuz bir durum makinesine dönüştürür ve yürütme ayrı adımlarda bu durum makinesinde ilerler. Her adım geçerli TaskScheduler (ile erişilen TaskScheduler.Current, varsayılan olarak TaskScheduler.Default) veya geçerli SynchronizationContextüzerinde zamanlanır. TaskScheduler kullanılırsa, yöntemindeki her adım bu Tasköğesine geçirilen bir TaskScheduler örneği temsil eder. Bu nedenle, Task içinde .NET iki kavramsal şeyi temsil edebilir:

  1. Zaman uyumsuz, beklenebilen bir işlem. Yukarıdaki DelayExecution() yönteminin yürütülmesi, Task ile temsil edilir ve beklenebilir.
  2. Zaman uyumlu bir iş bloğu. Yukarıdaki yöntem içindeki DelayExecution() her aşama bir Taskile temsil edilir.

Kullanıldığında, TaskScheduler.Default devamlılıklar doğrudan .NET ThreadPool üzerinde zamanlanır ve bir Task nesnesi içine sarılmaz. Devamlılıkların Task örneklerinde sarmalanması saydam bir şekilde gerçekleşir, bu nedenle geliştiricilerin bu uygulama ayrıntılarından genellikle haberdar olması gerekmez.

Orleans için görev zamanlaması

Her taneli etkinleştirmenin tek TaskScheduler yürütme modelini uygulamaktan sorumlu kendi örneği vardır. Dahili olarak, bu TaskScheduler ve ActivationTaskScheduleraracılığıyla WorkItemGroup uygulanır. WorkItemGroup, sıralanmış görevleri bir Queue<T> içinde tutar (burada T dahili olarak bir Task'dir) ve IThreadPoolWorkItem uygular. Her TaskWorkItemGroup şu anda sıralanmış olan öğeyi yürütmek için kendisini .NET üzerinde zamanlar. .NET ThreadPool, WorkItemGroup'in IThreadPoolWorkItem.Execute() yöntemini çağırdığında, WorkItemGroup kuyruktaki Task örneklerini tek tek yürütür.

Her bir dilimin kendisini .NET'te ThreadPoolzamanlayarak yürüten bir zamanlayıcısı vardır:

Orleans .NET ThreadPool'da kendilerini zamanlayan tanecikler.

Her zamanlayıcı bir görev kuyruğu içerir:

Zamanlanmış görevlerin zamanlayıcı kuyruğu.

.NET ThreadPool , sıraya alınan her iş öğesini yürütür. Bu, tahıl zamanlayıcılarının yanı sıra Task.Run(...) yoluyla zamanlananlar gibi diğer iş öğelerini de içerir.

.NET ThreadPool'da çalışan tüm zamanlayıcıların görselleştirmesi.

Uyarı

Bir parçacığın zamanlayıcısı aynı anda yalnızca bir iş parçacığında çalıştırılabilir, ancak her zaman aynı iş parçacığında çalıştırılmaz. .NET ThreadPool, grain'in zamanlayıcısı her defasında yürütüldüğünde farklı bir iş parçacığı kullanmakta serbesttir. Tahılın zamanlayıcısı tek seferde yalnızca bir iş parçacığında yürütülmesini sağlar ve tanelerin tek iş parçacıklı yürütme modelini uygular.