C # 'da ValueTask nasıl kullanılır?

Zaman uyumsuz programlama epey bir süredir kullanılmaktadır. Son yıllarda async ve wait anahtar kelimelerinin tanıtılmasıyla daha güçlü hale getirildi. Uygulamanızın yanıt hızını ve verimini artırmak için eşzamansız programlamadan yararlanabilirsiniz.

C # 'da zaman uyumsuz bir yöntemin önerilen dönüş türü Görev'tir. Bir değer döndüren zaman uyumsuz bir yöntem yazmak istiyorsanız Task döndürmelisiniz. Bir olay işleyicisi yazmak isterseniz, bunun yerine void döndürebilirsiniz. C # 7.0'a kadar, zaman uyumsuz bir yöntem Task, Task veya void döndürebilirdi. C # 7.0 ile başlayarak, zaman uyumsuz bir yöntem de ValueTask (System.Threading.Tasks.Extensions paketinin bir parçası olarak kullanılabilir) veya ValueTask döndürebilir. Bu makale, C # 'da ValueTask ile nasıl çalışabileceğimizin bir tartışmasını sunar.

Bu makalede verilen kod örnekleriyle çalışmak için sisteminizde Visual Studio 2019 yüklü olmalıdır. Halihazırda bir kopyanız yoksa, Visual Studio 2019'u buradan indirebilirsiniz.

Visual Studio'da bir .NET Core konsol uygulaması projesi oluşturun

Öncelikle Visual Studio'da bir .NET Core konsol uygulaması projesi oluşturalım. Sisteminizde Visual Studio 2019'un kurulu olduğunu varsayarak, Visual Studio'da yeni bir .NET Core konsol uygulaması projesi oluşturmak için aşağıda özetlenen adımları izleyin.

  1. Visual Studio IDE'yi başlatın.
  2. "Yeni proje oluştur" u tıklayın.
  3. "Yeni proje oluştur" penceresinde, görüntülenen şablon listesinden "Konsol Uygulaması (.NET Core)" öğesini seçin.
  4. Sonrakine tıkla.
  5. Daha sonra gösterilen "Yeni projenizi yapılandırın" penceresinde, yeni projenin adını ve yerini belirtin.
  6. Oluştur'u tıklayın.

Bu, Visual Studio 2019'da yeni bir .NET Core konsol uygulaması projesi oluşturacaktır. Bu projeyi, bu makalenin sonraki bölümlerinde ValueTask'ın kullanımını göstermek için kullanacağız.

ValueTask'ı neden kullanmalıyım?

Görev, bazı işlemlerin durumunu, yani işlemin tamamlanıp tamamlanmadığını, iptal edilip edilmediğini, vb. Temsil eder. Zaman uyumsuz bir yöntem, bir Task veya bir ValueTask döndürebilir.

Şimdi, Task bir başvuru türü olduğundan, zaman uyumsuz bir yöntemden bir Task nesnesinin döndürülmesi, yöntem her çağrıldığında nesnenin yönetilen yığın üzerinde tahsis edilmesini gerektirir. Bu nedenle, Task'ı kullanırken bir uyarı, yönteminizden bir Task nesnesi her döndürdüğünüzde, yönetilen yığın içinde bellek ayırmanız gerektiğidir. Yönteminiz tarafından gerçekleştirilen işlemin sonucu hemen elde edilirse veya eşzamanlı olarak tamamlanırsa, bu tahsis gerekli değildir ve bu nedenle maliyetli hale gelir.

İşte ValueTask'ın kurtarmaya geldiği yer burasıdır. ValueTask iki ana fayda sağlar. Birincisi, ValueTask, yığın ayırmaya ihtiyaç duymadığı için performansı artırır ve ikincisi, uygulanması hem kolay hem de esnektir. Sonuç hemen kullanılabilir olduğunda zaman uyumsuz bir yöntemden Task yerine ValueTask döndürerek, burada "T" bir yapıyı temsil ettiğinden ve C # 'da bir yapı bir değer türüdür ("T" nin aksine Görev, bir sınıfı temsil eder).

Görev ve ValueTask, C # 'da iki birincil "beklenebilir" türü temsil eder. Bir ValueTask'ı engelleyemeyeceğinizi unutmayın. Engellemeniz gerekiyorsa, ValueTask'ı AsTask yöntemini kullanarak bir Göreve dönüştürmeniz ve ardından bu referans Task nesnesini engellemeniz gerekir.

Ayrıca, her bir ValueTask'ın yalnızca bir kez kullanılabileceğini unutmayın. Burada "tüket" sözcüğü, bir ValueTask'ın işlemin tamamlanmasını eşzamansız olarak bekleyebileceğini (beklediğini) veya bir ValueTask'ı Göreve dönüştürmek için AsTask'tan yararlanabileceğini belirtir. Ancak, bir ValueTask yalnızca bir kez tüketilmeli ve ardından ValueTask göz ardı edilmelidir.

C # 'da ValueTask örneği

Bir Task döndüren zaman uyumsuz bir yönteminiz olduğunu varsayalım. Aşağıda verilen kod snippet'inde gösterildiği gibi Task nesnesini oluşturmak için Task.FromResult'tan yararlanabilirsiniz.

genel Görev GetCustomerIdAsync ()

{

    return Task.FromResult (1);

}

Yukarıdaki kod parçacığı, zaman uyumsuz durum makine büyüsünün tamamını oluşturmaz, ancak yönetilen yığın içinde bir Task nesnesi tahsis eder. Bu ayırmadan kaçınmak için, aşağıda verilen kod parçacığında gösterildiği gibi bir ValueTask'tan yararlanmak isteyebilirsiniz.

genel ValueTask GetCustomerIdAsync ()

{

    yeni ValueTask (1) döndür;

}

Aşağıdaki kod parçacığı, eşzamanlı bir ValueTask uygulamasını gösterir.

 genel arabirim IR deposu

    {

        ValueTask GetData ();

    }

Repository sınıfı, IRepository arayüzünü genişletir ve aşağıda gösterildiği gibi yöntemlerini uygular.

    genel sınıf Deposu: IRepository

    {

        genel ValueTask GetData ()

        {

            var değer = varsayılan (T);

            yeni ValueTask (değer) döndür;

        }

    }

GetData yöntemini Main yönteminden nasıl çağırabileceğiniz aşağıda açıklanmıştır.

statik geçersiz Ana (dize [] değiştirgeler)

        {

            IRepository repository = new Repository ();

            var sonuç = repository.GetData ();

            eğer (sonuç.IsCompleted)

                 Console.WriteLine ("İşlem tamamlandı ...");

            Başka

                Console.WriteLine ("İşlem tamamlanmadı ...");

            Console.ReadKey ();

        }

Şimdi depomuza başka bir yöntem ekleyelim, bu sefer GetDataAsync adlı asenkron bir yöntem. İşte değiştirilmiş IRepository arayüzünün nasıl görüneceği.

genel arabirim IR deposu

    {

        ValueTask GetData ();

        ValueTask GetDataAsync ();

    }

GetDataAsync yöntemi, aşağıda verilen kod snippet'inde gösterildiği gibi Repository sınıfı tarafından uygulanır.

    genel sınıf Deposu: IRepository

    {

        genel ValueTask GetData ()

        {

            var değer = varsayılan (T);

            yeni ValueTask (değer) döndür;

        }

        genel zaman uyumsuz ValueTask GetDataAsync ()

        {

            var değer = varsayılan (T);

            Task.Delay (100) bekliyor;

            geri dönüş değeri;

        }

    }

C # 'da ValueTask'ı ne zaman kullanmalıyım?

ValueTask'ın sağladığı avantajlara rağmen, Görev yerine ValueTask'ı kullanmanın bazı değiş tokuşları vardır. ValueTask, iki alan içeren bir değer türüdür, Görev ise tek alanlı bir başvuru türüdür. Bu nedenle, bir ValueTask kullanmak, bir yöntem çağrısı bir yerine iki veri alanı döndüreceğinden daha fazla veriyle çalışmak anlamına gelir. Ayrıca, bir ValueTask döndüren bir yöntemi beklerseniz, bu eşzamansız yöntemin durum makinesi de daha büyük olacaktır - çünkü bir Görev durumunda tek bir başvuru yerine iki alan içeren bir yapıyı barındırması gerekir.

Ayrıca, bir zaman uyumsuz yöntemin tüketicisi Task.WhenAll veya Task.WhenAny kullanıyorsa, bir zaman uyumsuz yöntemde dönüş türü olarak ValueTask kullanmak maliyetli olabilir. Bunun nedeni, ValueTask'ı AsTask yöntemini kullanarak Göreve dönüştürmeniz gerekmesidir; bu, önbelleğe alınmış bir Görev ilk etapta kullanılmış olsaydı kolayca önlenebilecek bir ayırmaya neden olur.

İşte başparmak kuralı. Her zaman eşzamansız olacak bir kod parçanız olduğunda, yani işlem hemen tamamlanmayacağı zaman Task'ı kullanın. Eşzamansız bir işlemin sonucu zaten mevcutsa veya önbelleğe alınmış bir sonucunuz olduğunda ValueTask'tan yararlanın. Her iki durumda da, ValueTask'ı düşünmeden önce gerekli performans analizini yapmalısınız.

C # ile daha fazlasını nasıl yapabilirsiniz:

  • C'de değişmezlik nasıl kullanılır
  • C # 'da const, salt okunur ve statik nasıl kullanılır?
  • C # 'da veri ek açıklamaları nasıl kullanılır
  • C # 8'de GUID'lerle nasıl çalışılır
  • C # 'da soyut bir sınıf ve arabirim ne zaman kullanılır?
  • C # 'da AutoMapper ile nasıl çalışılır
  • C # 'da lambda ifadeleri nasıl kullanılır
  • C # 'ta Action, Func ve Predicate temsilcileriyle nasıl çalışılır?
  • C # 'da temsilcilerle nasıl çalışılır
  • C # 'da basit bir kaydedici nasıl uygulanır
  • C # 'da özniteliklerle nasıl çalışılır
  • C # 'da log4net ile nasıl çalışılır
  • Depo tasarım modeli C # 'da nasıl uygulanır?
  • C # 'da yansıma ile nasıl çalışılır
  • C # 'da dosya sistemi gözlemcisi ile nasıl çalışılır
  • C # 'da geç başlatma nasıl gerçekleştirilir
  • C # 'da MSMQ ile nasıl çalışılır
  • C # 'da uzatma yöntemleriyle nasıl çalışılır
  • C # 'da lambda ifadeleri nasıl kullanılır
  • Volatile anahtar kelime C # 'da ne zaman kullanılır?
  • C # 'da getiri anahtar kelimesi nasıl kullanılır
  • C # 'da polimorfizm nasıl uygulanır?
  • C # 'da kendi görev zamanlayıcınızı nasıl oluşturabilirsiniz?
  • C # 'da RabbitMQ ile nasıl çalışılır
  • C # 'da bir demet ile nasıl çalışılır
  • C # 'da sanal ve soyut yöntemleri keşfetmek
  • C # 'da Dapper ORM nasıl kullanılır
  • C # 'da flyweight tasarım desenini kullanma