dotnet-de-asinxron-proqramlasdirma-modeli

.NET-də Asinxron Proqramlaşdırma modeli

Asinxron Programlaşdırma modeli (bundan sonra APM) Microsoft-un təqdim etdiyi ilk asinxron proqramlaşdırma variantlarından biridir. Bunun hesabına arxa planda Thread yaradılma prosesinə qənaət etmək olur. MultiThread proqramlaşdırma istifadə edərkən hər metod başına ayrı Thread yaradırdıq. Bu o deməkdir ki, 10 metodumuz varsa deməli 10 Thread yaratmalı idi. Düzdür, ThreadPool ortaya çıxdıqdan sonra situasiya xeyli dərəcədə dəyişdi, artıq Thread yaradılması prosesi CLR-in öhdəsinə verildi. Asinxron proqramlaşdırma modelimiz də arxa planda ThreadPool-u istifadə edən metodlar toplusudur.

               APM metodları BeginXXX() ilə başlayır, EndXXX() ilə bitir. Bu o deməkdir ki, əgər metod Begin ilə başlayırsa onu sinxron vəziyyətə keçirib cavabı almaq üçün yekunda EndXXX metodunu çağırırıq.

               Hazırda APM köhnəlmiş APİ sayılsa da sonrakı dərslərdə izah edəcəyimiz bir sıra yeni Asinxron proqram yazma texnikaları yekun etibarilə APM-in işləmə prinsipi ilə demək olar ki eynidir. Ona görə APM-i başa düşmək mütləqdir. .NET-də yazılmış köhnə proqramları support edərkən APM çox işinizə yarayacaq.

 Asinxron proqramlaşdırma nədir?

               Asinxron proqramlaşdırma imkan verirki birdən artıq işi eyni zamanda görək. Bunu çox vaxt multiThreading ilə qarışdırırlar amma multiThreadingdə iş başına bir Thread yaradılsa da asinxron proqramlaşdırmada ola bilsinki 10 iş üçün 3-5 arası Thread ayrılsın. Yəni threadlərin yaradılma prosesinə xeyli qənaət edirik. Bir çox asinxron mexanizmlər arxa planda ümümiyyətlə Thread istifadə etmədən işi yekunlaşdıra bilirlər.

 APM nədir?

 .NET-də Asinxron proqram yazmaq üçün bir sıra variantlar var. Bu variantlardan biri APM-dir.  APM .NET kitabxanasında əvvəli BeginXXX EndXXX  ilə bitən metodlardan ibarətdir. Onlar əməliyyatları asinxron şəkildə yerinə yetirirlər və bununla da ana Thread(patok)-ə yük düşmür. Adəti üzrə verilənlər bazasıyla, fayllarla işləyən zaman ən çox asinxron proqramlaşdırma istifadə edirik.

               Bir  çox external resurslarla işləyən  .NET klaslarında əməliyyatları asinxron yerinə yetirmək üçün hazır metodlar verilib. Misal üçün buna FileStream klasını nümunə göstərə bilərik. FileStream klası əməliyyatları sinxron yerinə yetirməklə yanaşı, asinxronluq üçün də bir sıra metodlara malikdir. Aşağıdakı kod nümunəsində fayldan məlumatı oxumağın APM modelinə baxaq. Files qovluğunda MyFile.txt faylımız var və həmin faylı oxumaq üçün kiçik bir proqram yazaq. (kodları github adresimizdən yükləyə bilərsiniz)

            //preparing for read in async manner
            FileStream fs = new FileStream(fullPath, FileMode.Open);

            byte[] array = new byte[fs.Length];


            //we do operation in async manner so right here we will not get result..
          IAsyncResult asyncResult = fs.BeginRead(array, 0, array.Length,(t)=>
          {
              MessageBox.Show("Reading file completed successfully");
           fs.Dispose();
          },null);
            //so,you can put here any code you want..
            //here also....
            this.Text = "File reading started before this message";

               Gördüyümüz kimi , asinxron əməliyyat ayrıca bir xətlə icra olunmaya başlayır və bunun əsas Thread-ə heç bir təsiri olmur, əsas Thread yenə də boşda qalır və biz istədiyimiz əməliyyatı yerinə yetirə bilərik paralel olaraq. Burada BeginRead metodu əməliyyatı asinxron icra edir. FileStream klasının Read metodundan fərqli olaraq BeginRead əlavə 2 parametr qəbul edir. Bu parametrlərdən birinci asixnron əməliyyat başa çatan zaman hansı işin yerinə yetiriləcəyini göstərir, 2ci parametr isə həmin ilk deleqata hansı arqumentin ötürüləcəyini göstərir. Həmin parametrləri istifadə edərək alınan cavabı qrafiki interfeysdə göstərək.

 private void btn_fileStreamRead_Click(object sender, EventArgs e)
        {
            //prepare path to file
           string fullPath = ApplicationPath.PathTo("Files/MyFile.txt");
            
            //preparing for read in async manner
            FileStream fs = new FileStream(fullPath, FileMode.Open);
            byte[] array = new byte[fs.Length];




            var c = SynchronizationContext.Current;


            //we do operation in async manner so right here we will not get result..
          IAsyncResult asyncResult = fs.BeginRead(array, 0, array.Length,(t)=>
          {
              byte[] arrayData = t.AsyncState as byte[];


              //emulate long reading..
              Thread.Sleep(1200);
              c.Post(p =>
              {
                  rctxbx_data.Text = Encoding.UTF8.GetString(arrayData);
              }
              ,null);
              fs.Close();
          },array);


            //here we always will wait async for operation to complete
            fs.EndRead(asyncResult);
            //so,you can put here any code you want..
            //here also....
            this.Text = "File reading started before this message";
           


        }

Burada əlavə istifadə olunan sinxronizasiya konteksti haqda ayrıca məqaləmiz olacaq, sadəcə bilək ki, Uİ Thread-dəki komponentləri update etmək üçün ona ehtiyacımız var.

(kodları github adresimizdən yükləyə bilərsiniz)

 EndXXX() metodunu nəzaman istifadə etməliyəm?

               Əgər asinxron əməliyyatdan məcburi şəkildə əsas Threadi dayandıraraq cavab almaq lazımdırsa ozaman EndXXX metodundan istifadə edirik . Bu metod ana Threadi donduraraq asinxron əməliyyatdan cavab gəlməsini gözləyir. Metodun işləməsi üçün BeginXXX metodunun qaytardığı İAsyncResult interfeysini ona arqument olaraq vermək lazımdır.

Tural

Tural Süleymani

Süleymani Tural Microsoft-un MCSD statuslu mütəxəssisidir, 2008-ci ildən bu yana proqramlaşdırma üzrə tədris aparır

Müəllifin bu dildə ən son postları

Bu yazıları da bəyənə bilərsiniz