04/12/2015 18

C# ile ASYNC ifadesi - Asenkron Metod Çalıştırma -

Herkese merhaba. Bu yazıda sizlere C# ile Async ifadesinden bahsedeceğim. Bu metod ile çalıştırılan bir metodun dönmesini beklemeden yeni metodları çalıştırabileceğiz. Şimdi konumuza geçelim.

Async, await ifadeleri: Bazı metodlar çalışma esnasında yaptığı işlemin sonucunu hemen döndüremezler. Belki harici dosyalar ile çalışan bir metoddur. Bunu ben bilemem. Fakat bu sebepten dolayı işlemini yavaş bitirebilir. Diğer metodun bu metodu beklediğini düşünelim ve programımızı nasıl yavaşlatacağını düşünelim. İşte bu yüzden fonksiyonlarımızı tanımlarken ASYNC ifadesi ile asenkron bir şekilde çalışmasını sağlarız.

Async metodunun bir diğer faydası ise çalışma esnasında diğer metodları bloke etmemesidir. Yani diğer metodların çalışmasını engellemesidir. Çünkü döndürdüğü değerler diğer metodları ilgilendirmez. Genellikle void ifadeler async olarak tanımlanır fakat int string bool gibi ifadelerde async olarak tanımlanabilir.

Şunuda unutmamak gerekir ki bir async fonksiyonun çerisinde await ifadesi yoksa eğer o metod yine senkronize bir şekilde çalışır. Mutlaka içerisine await ifadesini koymalıyız. Şimdi bir örnek yapalım ve bu örnekte async ve await ifadelerini kullanarak bir asenkron metod oluşturalım.

İlk olarak bir fonksiyon oluşturalım ve onu çalıştılarım. Daha sonra o fonksiyonun işlemini bitirmesini bekleyelim.

Bundan sorna program çalışırken ekrana mesajlar verdirelim. Bu mesajlar sayesinde metodumuzun çalıştığını greileceğiz. Mesajları verdirmemizin amacı bu metodların çalıştığını görmek zaten.

Async bir metod oluşturalım ve bu metod çalışmaya başlasın ve asenkron olarak işlemine devam etsin ve işlemini yapsın. Bu metod ile bir dosya yazdırve okuma işlemi yapalım ki nasıl çalıştığını görelim. Şimdi aşağıdaki kodları dikkatlice takip edelim.

Bu uygulama .Net framewordk 4.5 versiyonu ile yapılmıştır.

 

using System;
using System.IO;
using System.Threading.Tasks; //Task işlemi ile birlikte çalıştırdığımız için bu sınıfı ekledik

class Program
{
    static void Main()
    {
	// Bir task oluşturduk
	Task islem = new Task(asenkron_islem);
        //Task nesnemiz çalışmaya başladı
	islem.Start();
        //ve task nesnemizin başladığı işi bitirmesini bekleme fonksiyonumuz
	islem.Wait();
        //işlem bitince console bir tuşa basmamızı beklesin
	Console.ReadLine();
    }

    static async void asenkron_islem()
    {
	/ Yavaşlatmanın olacağı fonksiyon. bu fonksiyon olabildiğince yavaş çalışacak
	Task gorev = dosya_isleme_fonksiyonu("C:/thecodeprogram.txt");

        //Yukarıdaki fonksiyon çalışırken işlem yaptığımızda fonksiyon buraya geçer ve burası çalışır
        //Yani yukarıdaki fonksiyonun bitmesini beklemeden bu işlem çalışır
        //işte asenkron metod çalıştırma işlemi bu şekilde olur
	Console.WriteLine("Lütfen yukarıdaki işlemin bitmesini bekleyin");

        //Aşağıdaki await ifadesinden dolayıda aşağıdaki fonksiyon ekler ve
        //metod sonuç döndürünce işlem yapar
	int x = await gorev;
	Console.WriteLine("Sonuc: " + x);
    }

    static async Task dosya_isleme_fonksiyonu(string dosya)
    {
	int sayac = 0;

        //burada dosyayı okuyoruz dikkat edin içeride await ifadesini kullandık
        //bu sayede bu metod asenkron olarak çalışacaktır.
	using (StreamReader oku = new StreamReader(dosya))
	{
	    string veri = await oku.ReadToEndAsync();
            Console.WriteLine("Yavaş fonksiyon aşladı");

	    sayac += veri.Length;

            //burada amacımız çalışan metodu yavaşlatmak
            //yavaşlayınca bizim asenkron çalışan metodlarımızın normaldeki işlem bitirme sırası değişecek
            //bizde asenkron çalışma durumunu kontrol edeceğiz.
	    for (int i = 0; i <; 99999; i++)
	    {
		int x = veri.GetHashCode();
		if (x == 0)
		{
		    sayac--;
		}
	    }
	}
	Console.WriteLine("Yavaşlatma sonlandı");
	return sayac;
    }
}


Program Çalışırken Çıktı

Yavaş Fonksiyon Başladı
Lütfen Yukarıdaki fonksiyonun bitmesini bekleyin

Program Sonu Alınan Çıktı

Yavaş Fonksiyon Başladı
Lütfen Yukarıdaki fonksiyonun bitmesini ekleyin
Yavaşlatma Sonlandı
Sonuc: 3376454

Bu programda yavaş çalışacak olan fonksiyon işlemini bitirinceye kadar program kapanmaz çünkü programın kapanması için o metodun bitirilmesi gerekir. Fakat o sonraki fonksiyon o fonksiyonun bitmesini beklemez. Çünkü asenkron olarak çalışıyor ve içerisinde await anahtar kelimesi bulunmakta. Bu sayede metodlarımızı asenkron olarak çalıştırarak metodları birbirini beklemeden çalıştırmayı başarıyoruz.

Normal yollarda normal metod oluşturma yöntemiyle bu işlemi yapamayız. Çünkü normal metod yönteminde metodlar çalışma sırasına göre birbirini beklemek zorundadır.

Bu yöntemin amacı programın satırlarının birbirlerini beklemeden işlevlerini hızlı bir şekilde bitirmesidir. Bu sayede programın çalışırken daha hızlı işlev görmesidir. Bu çalışma sistemi C# içerisindeki delegate sistemine benzer. Delegate mantığı ile fonksiyonları farklı delegate nesneleri ile farklı treadlar aracılığı ile çalıştırabiliyoruz. Bu şekildede fonksiyonlar birbirlerini beklemezler. Çünkü çalıştırıcı delegate nesneleri farklı delegate nesneleridir.

Asenkron çalışma mantığında programın donmaları engellenir. Bazen while döngülerinde program donar ve cevap vermez. Fakat asenkron çalışma ile program donmaz ve çalışmasına devam eder.

Aşağıdaki program ile tekrar bir inceleme yapalım ve sonuçları görelim...

using System;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
	while (true)
	{
	    // programın asenkron metodu başlıyor
	    asenkron_metod();
	    // Programa kullanıcı girişi sağlanıyor ve ekrana yazdırılıyor
	    string girilen = Console.ReadLine();
	    Console.WriteLine("Girilen Değer: " + girilen);
	}
    }

    static async void asenkron_metod()
    {
	// asenkron çalışacak olan fonksiyon
	int i = await Task.Run(() => surekli_calisacak());
	Console.WriteLine("işlem: " + i);
    }

    static int surekli_calisacak()
    {
	// Programın içerisinde çağrılacak olan sürekli çalışan fonksiyon
	int sayac = 0;
	for (int i = 0; i < 100; i++)
	{
	    for (int j = 0; j < 1000000; j++)
	    {
		string deger= j.ToString();
		if (deger == null)
		{
		    return 0;
		}
		sayac += deger.Length;
	    }
	}
	return sayac;
    }
}


Program Çıktısı

thecode
Girilen Değer: thecode
pogram
Girilen Değer: program

işlem: 12345665
deneme //arada bu değeri girdik ve o işlemi yaptıktan fakat diğer işlemin çalışmasını engellemedi
Girilen Değer: deneme
işlem: 12345665
işlem: 12345665
işlem: 12345665
işlem: 12345665
Console uygulamalarında main metodu kesinlikle ve kesinlikle async olarak tanımlanamaz. Çünkü Main fonkiyonu programın ana fonkiyonu main fonksiyonudur. Bu fonksiyon async olamaz. Koymaya çalışırsanız programda hata alırsınız. Program çalışmaz.

using System;
using System.Threading.Tasks;

class Program
{
    static async void Main()
    {
    }
}

  • Async ve await ifadeleri programın içerisindeki kodların asenkron bir şekilde çalışması için gereken bir düzendir. Syntax olarak bibirlerine bağlıdırlar. Kodların okunmasını ve çalışmasını kolaylaştırırlar.
  • Async ve await ifadeleri ile programımızda daha karmaşık kodları daha hızlı bir şekilde çalıştırabiliriz. İşlemleri asenkron olarak çalıştırırken hata felan alırsak visual studio zaten bize uyarı verecektir. Bizde hatamızı düzeltiriz.
  • StreamReader gibi metodları çalıştırırken içeride await ifadesini bulundurmamız gerekmektedir. Bu ifadeyi bulundurmazsak program istediğimiz asenkron metodları çalıştırmayacaktır.
  • Metodların içerisine girmesi için async olarak kullanmak gerekir. Async metodların çalışması içinde kullanılırken await ifafadesini bulundurmamız gerekmektedir.
  • Normal metodlarda asenkron metod olarak kullanılabilir.
  • Şunu belirtmek isterim. Asenkron çalışma aynı anda birden fazla işlem yapabiliyor diye multi thread olarak anlaşılmamalı. Kod tek bir thread içerisinde asenkron bir şekilde çalışır. Fakat multi thread kodlarda birden fazla thread bulunmaktadır.
  • Task.Run metodunu kullanarak metodları Multi Thread Mantığı ile çalıştırma imkanının olduğunuda belirtmek isterim. Fakat yinede söylüyorum asenkron çalışma multi thread değildir.
  • Aynı thread içerisinde birden fazla metod çalışır. Bu metodlar birbirlerini beklemeden işlemini yapabilir.
  • Asenkron çalışma sayesinde başka threadlar oluşturmadan multi thread mantığı ile işlem yapmamıza olanak tanır. Bu sayede programımızı multi thread kullanıyormuşçasına hılı çalıştırabiliriz. Fakat bu işlem yine tek bir thread içerisinde olur.
 

Bu yazımızda bu kadar arkadaşlar

Takipte Kalın

İyi Çalışmalar

Burak Hamdi Tufan


Tags

Share this Post



Post a Comment

Success! Your comment sent to post. It will be showed after confirmation.
Error! There was an error sending your comment.

Comments

    There is no comment. Be the owner of first comment...