C#’ta Task.FromResult Metodu

Merhaba,

Programlama yapıları üzerine çalışmaların yanında harici yazılı-görsel materyaller üzerinden de genel kamuoyu takibimede devam etmekteyim. Haliyle geçenlerde oturmuş şöyle blogdaşlar üzerinde bir göz gezdirmekteyken Syn. İlkay İlknur hocamızın adreste verdiğim makalesinde basit ama oldukça etkili bir konuyla karşılaştım. Birazdan bizimde detaylandıracağımız bu konuda İlkay Hocamız benimde farklı yaklaşımlar sergilediğim bir duruma Task.FromResult metodunu tanımlayarak çözüm üretmemizi tavsiye etmektedir. Şimdi gelin; hangi durumda, ne amaçla Task.FromResult metodunu kullanacağımızı inceleyelim.

Biliyoruz ki, Task sınıfı herhangi bir asenkron operasyonun çalışma sürecindeki tüm bilgilerini tutan bir sınıftır. Haliyle async ve await komutları Task tipinden faydalanarak gereken yapıları oluşturmakta ve sürecin asenkron bir şekilde ilerlemesini sağlamaktadırlar.

Şimdi konumuzun derinliklerine yavaş yavaş girelim. Öncelikle aşağıdaki kod bloğunu inceleyiniz.

        static Task<int> OrnekMetod()
        {
            ...
        }

Yukarıda görmüş olduğunuz metod Task<int> tipinde geri dönüş değerine sahip bir metoddur. Bu metodun çalışabilmesi için Task<int> tipinde bir değeri geriye döndürmesi gerekmektedir. Bu gereksinimi gidermek için Task tipine özel üç farklı durumu aşağıdaki gibi göz önüne alalım;

  • 1. Durum
    Makalemizin üst satırlarında belirttiğimiz gibi Task tipi asenkron yapılanma için özel bir tiptir ve async – await komutları bu tipi kullanarak gerekli yapılanmayı sağlamaktadır. Yani anlayacağınız ilgili metodumuz async – await keywordleri kullanacağı zaman otomatik olarak belirtilen tipte geriye bir değer döndürecektir. Şöyle ki;

            static async Task<int> OrnekMetod()
            {
                return 123;
            }
    

    Görüldüğü üzere async keywordü ile metodumuzu işaretlediğim zaman geriye direkt olarak “123” değerini gönderebilmekteyim. Compiler async komutu sayesinde bu metodun bir asenkron süreç geçirebileceğini algılamakta ve içerisindeki geri dönüş değerini Task tipiyle otomatik olarak return etmektedir. Kendi gözlerinizle görmek için buyrun;
    C#'ta Task.FromResult Metodu

    Ee tabi ki de bu işi async komutu Task tipiyle sağlamaktadır. Eğer ki, async komutu olmaksızın “123” değerini return etmeye çalışsaydık akıbetimiz aşağıdakinden farksız olacaktır.
    C#'ta Task.FromResult Metodu

  • 2. Durum
    Bildiğiniz Task<int> tipinde bir nesne oluşturup geri döndürmektedir.

            static Task<int> OrnekMetod()
            {
                return new Task<int>(() => { return 123; });
            }
    

    Bu şekilde bir çözüm çokta aklı selim bir uygulama değildir. Nihayetinde Task örneği oluşturabilmek için bir metoda ihtiyacımız var ki ben örnekte Lambda olarak ifade etmekteyim.

    Ya da

    Task.Run metodunu kullanarak ihtiyacımızı da giderebilirdik.

            static Task<int> OrnekMetod()
            {
                return Task.Run<int>(() => { return 123; });
            }
    

    Tabi ki de Task.Run metodunu bu kadar ucuz işlemler için ve bilinçsiz bir şekilde kullanmamanızı öneririm. Ayriyetten görüldüğü üzere Task.Run metoduda içerisinde metod istemektedir.

  • 3. Durum
    1. durumumuzda görüldüğü üzere async – await komutları devreye sokulduğu zaman Task nesnesi yaratmadan direkt ilgili değeri return edebiliyoruz. 2. durumda da görüldüğü üzere ortada bir asenkron operasyon yokken Task yaratmak durumunda kalıyoruz. İşte bu 3. durum aslında 2. duruma bir alternatif olarak sunacağım ve konumuzun aslen içeriğini teşkil edecek kısımdır.

    Eğer ki yapılacak işlem asenkron bir yaklaşım sergilemeyecek ve geriye Task tipinde bir değer döndürmemiz gerekecekse Task.FromResult metodunu kullanmamız yeterlidir. Task.FromResult metodu; yeni bir Task nesnesi yaratarak, yaratılan bu nesnenin görevlerinin tamamlanmış olarak işaretlenmesini ve parametre olarak verilen değerin görevin sonucu olarak belirlemesini sağlayacak bir metotdur. Kısaca;

            static Task<int> OrnekMetod()
            {
                return Task.FromResult(123);
            }
    

    Bu şekilde Task.FromResult metodu sayesinde tamamlanmış bir Task objesi yaratmış olduk ve değer olarakta “123” değerini geri döndürmüş olduk.

Bazı Durumlarda Senkron, Bazı Durumlarda ASenkron Metod

Bu işlem için aşağıdaki kod bloğunu inceleyiniz.

    class Odeme
    {
        public async void TahsilatYap(double Tutar)
        {
            try
            {
                var Sonuc = await Tahsilat(Tutar);
                Console.WriteLine(Sonuc);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
        Task<bool> Tahsilat(double Tutar)
        {
            if (Tutar < 100)
                return Task.FromException<bool>(new TutarException());
            else
            {
                if (Tutar >= 100 && Tutar < 200)
                    return Task.FromResult(false);
                else
                    return Task.Run<bool>(() =>
                     {
                         while (true)
                         {
                             if (DateTime.Now.Second == 10)
                             {
                                 Console.WriteLine("Ödeme yapıldı.");
                                 return true;
                             }
                         }
                     });
            }
        }
    }

    class TutarException : Exception
    {
        public TutarException() : base("Ödeme tutarı 100 TL'den aşağı olamaz.")
        {

        }
    }

Gördüldüğü üzere “Odeme” sınıfı içerisinde “Tahsilat” metodu yapılacak tutarın “100” değerinden az olduğu durumda direkt metoddan çıkmaktadır. Eğer ki, “100” ile “200” değerleri arasında bir meblağda ödeme gerçekleştiriliyorsa gene senkron bir şekilde “false” değeri geriye döndürülmektedir. Eğer ki, ödenen tutar “200” değerinden fazla ise Task.Run metoduyla asenkron bir şekilde çalışma başlatılmakta ve 10. saniyede ödeme gerçekleştirilmektedir.

.NET 4.6.1 Versiyonunda Gelen Task.FromResult Benzeri Diğer Yapılar

.NET 4.6.1 versiyonunda Task.FromResult mantığında bir çok metod ve property yapıları gelmiştir. Son olarak bu yapılar üzerinde konuşarak makalemizi noktalayalım.

  • Task.FromException
    FromException metodu, yapılan asenkron işlemlerde bir aksaklık oluştuğu durumlarda Task tipini oluşturmakta ve geriye bir Exception fırlatmaktadır.

        class Program
        {
            static void Main(string[] args)
            {
                OrnekClass oc = new OrnekClass();
                oc.MetodCalistir();
                Console.Read();
            }
        }
    
        class OrnekClass
        {
            public async void MetodCalistir()
            {
                await Metod();
            }
            Task<int> Metod()
            {
                return Task.FromException<int>(new OrnekException());
            }
        }
    
        class OrnekException : Exception
        {
            public OrnekException() : base("Bu bir örnek Exception'dır.")
            {
    
            }
        }
    

    Görüldüğü üzere “OrnekException” isimli Exception’ımızı “OrnekClass” sınıfı içerisindeki “Metod” isimli metotda Task.FromException ile döndürmekteyiz. Aynı sınıf içerisinde bulunan “MetodCalistir” isimli metotla asenkron bir şekilde çalıştırmaktayız. “Main” metodunda ise ilgili yapıyı çağırdığımız zaman aşağıdaki sonuçla karşılaşmaktayız.
    C#'ta Task.FromResult Metodu

  • Task.FromCanceled
    Bir görev iptal edildiği zaman exception olarak geri dönen metotdur. Kullanımı aşağıdaki gibidir.

            Task<bool> AracGonder()
            {
                CancellationToken token = new CancellationToken(true);
                //token nesnesi sayesinde görevin iptal edildiğini belirtiyoruz.
                if (token.IsCancellationRequested)
                    //IsCancellationRequested özelliği görev iptalse true dönecektir.
                    return Task.FromCanceled<bool>(token);
                //token nesnesi görevin iptal olduğunu taşıdığından Task.FromCanceled metodunu return edebiliyoruz.
                else
                    return Task.FromResult(true);
            }
    
  • Task.CompletedTask
    Task.CompletedTask propertysi ise generic olmayan tamamlanmış bir Task tipi dönmemizi sağlamaktadır. Yani aşağıdaki örnekte olduğu gibi;

            Task OrnekMetod()
            {
                return Task.CompletedTask;
            }
    

Evet… Task sınıfı üzerinde static olarak ayarlanmış yapılardan etkili olanları detaylıca irdelediğimizi sanıyorum. Bundan sonra oluşturulacak görevlerde lüzumsuz nesne ve işlev kalabalığından kaçınarak bu yapıların kullanılmasına dikkat etmenizi tavsiye ederim.

Sonraki yazılarımda görüşmek üzere…
Şimdilik hoşçakalın…
İyi çalışmalar…

You may also like...

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

CAPTCHA (Şahıs Denetim Kodu) Resmi

*

Copy Protected by Chetan's WP-Copyprotect.