İlkay İlknur

just a developer...

C# 5.0 & VB.NET 11.0 Async ve Await İle Kolaylaşan Asenkron İşlemler

Merhaba Arkadaşlar,

C# 5.0 & VB.NET 11.0 Asenkron Programlama 5N1K (Ne,nerede,ne zaman,nasıl,neden,kim)  isimli yazımızda sizlerle C# 5.0 ile beraber gelecek olan Asenkron Programlama yeniliklerini incelemeye çalışmıştık. O yazımızda dilsel yeniliklerden bahsetmek yerine daha çok konseptsel olarak Asenkron Programlama’nın ne olduğundan, neden gün geçtikçe daha da önem kazandığından ve hangi noktalarda bazı sorunlar yarattığından bahsetmiştik. Bu yazımızda ise artık teorik kısmı bir kenara bırakıp gelen yenilikleri kod üzerinden incelemeye çalışıyor olacağız.

Yazımız boyunca Netflix üzerinden girilen yıla göre çekilen filmleri getiren bir uygulama geliştiriyor olacağız. Uygulama içerisinde de Netflix’in sunmuş olduğu OData(Open Data Protocol) servisinden faydalanacağız.

İlk olarak uygulamamızı Netflix’ten filmleri senkron olarak getirecek şekilde geliştiriyor olacağız. Sonrasında aynı uygulamayı şu anda elimizde bulunan imkanlarla asenkron hale getireceğiz ve son olarakta aynı uygulamayı C# 5.0 ile beraber gelen async ve await keywordlerini kullanarak geliştirip, aralarındaki farkları incelemeye çalışacağız. O zaman hemen senkron olarak verileri getiren uygulamamızı geliştirmeye başlayalım !

Senkron Programlama

İlk olarak uygulamamızın arayüzünü tasarlayarak işe başlayalım. WPF tabanlı uygulamamız oldukça basit bir arayüze sahip olacak. Kullanıcıdan alacağımız yıla göre verileri getirme işlemine başlayacağız ve bir panel içerisine söz konusu filmler ile ilgili bilgileri dolduracağız. Bu nedenle hemen arayüz kısmını tasarlayalım ve sonrasında kodlama tarafına geçelim.

<Grid>   
<Label Content="Filmin Çekilme Senesi" Height="28" HorizontalAlignment="Left"
 Margin="6,12,0,0" VerticalAlignment="Top" />   
<TextBox Height="23" HorizontalAlignment="Left" Margin="136,14,0,0"
 Name="txtMovieYear" VerticalAlignment="Top" Width="120" />   
<Button Content="Ara" Height="23" HorizontalAlignment="Left"
 Margin="278,13,0,0" Name="btnSearch" VerticalAlignment="Top"
 Width="75" Click="btnSearch_Click" />    
<ScrollViewer VerticalScrollBarVisibility="Auto" Margin="0,46,0,0">         
<WrapPanel Name="resultsPanel" Orientation="Horizontal"/>    
</ScrollViewer>
 </Grid>

 

Evet yazımız boyunca uygulamamızın arayüzü yukarıda gördüğünüz gibi olacak. Bu nedenle artık yazımız boyunca arayüz kısmına hiç değinmeyeceğiz ;).

Şimdi gelelim uygulamanın arka plan kodlarına:)

Kod tarafını geliştirmeye başlamadan önce Netflix’in developerlara sunmuş olduğu OData servisi ile ilgili bir kaç detaya dikkat etmek gerekiyor. Bunlardan en önemlisi de servisin paging mantığıyla çalışması. Servis her çağrıda maksimum 20 film kaydı geri dönmekte. Bu yüzden servise yapılan çağrı sonucunda toplamda kaç film döneceğini belli olmadığından, servis herhangibir film dönmeyene kadar iterasyonu sürdürmemiz gerekiyor.

Şimdi ilk olarak uygulama boyunca kullanacağımız ve Netflix servisinden dönecek olan filmleri temsil edecek, Movie isimli sınıfı tasarlayalım ve sonrasında da yine servis çağrıları ve parsing işlemleri sırasında kullanacağımız web adreslerini ve isim alanlarını(namespace) tanımlayalım.

XNamespace xa = "http://www.w3.org/2005/Atom"
XNamespace xd = "http://schemas.microsoft.com/ado/2007/08/dataservices"
XNamespace xm = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"; 
string query = "http://odata.netflix.com/Catalog/Titles?$filter=ReleaseYear eq" 
               +"{0}&$skip={1}&$top={2}&$select=Url,BoxArt";
class Movie
{             
 public string Title { get; set; }             
 public string Url { get; set; }             
 public string BoxArtUrl { get; set; }         
}

Yukarıda görmüş olduğunuz namespace tanımlamalarını Netflix’ten dönen cevabın parse edilmesi ve çalışma zamanında Movies tipinden birer nesne örneği haline çevrilmesi sırasında kullanıyor olacağız. Query ismini verdiğimiz değişkenimiz ise istekte bulunacağımız adresi tutmakta.

Sıra geldi yıl girişi yapıldıktan sonra iş akışını yöneteceğimiz metodu yazmaya. Yazımızın başında Netflix’in bir çağrıda maksimum 20 film döndüğünden bahsetmiştik. Bu nedenle bizim arka planda bir paging yapısı kurarak arka arkaya Netflix tarafına isteklerde bulunmamız gerekmekte ta ki Netflix’ten yaptığımız çağrı sonucunda hiç film kaydı gelmeyene kadar.

void LoadMovies(int year)         
{             
 resultsPanel.Children.Clear();             
 var pageSize = 10;             
 var imageCount = 0;             
 while (true)             
 {                 
 var movies = QueryMovies(year, imageCount, pageSize);                 
 if (movies.Length == 0) break;                 
 DisplayMovies(movies);                 
 imageCount += movies.Length;             
 }         
}

Gördüğünüz gibi basit bir sonsuz döngü oluşturduk ve 10’arlı gruplar halinde film bilgilerini bize getirecek olan istekleri yarattık. Her isteğin yanıtını aldıktan sonra bir sonraki 10’arlı grubun isteğini yaratıp Netflix’e gönderdik. Netflix’ten film dönmediğinde ise artık filmlerin sonuna geldiğimiz anlayarak sonsuz döngüyü sonlandırdık.

LoadMovies metodu içerisinde 2 farklı metot çağrısı icra edildiği görülmektedir. Bunlardan biri Netflix’e istekte bulunan ve Movie dizisi döndüren QueryMovies metodu, diğeri ise dönen Movies dizisini ekranda image olarak gösteren DisplayMovies metodudur.Öncelikle DisplayMovies metodunun geliştirmesini yapalım.

void DisplayMovies(Movie[] movies)

{            

 foreach (var movie in movies)             
 {                 
 var bitmap = new BitmapImage(new Uri(movie.BoxArtUrl));                 
 var image = new Image();                 
 image.Source = bitmap;                 
 image.Width = 110;                 
 image.Height = 150;                 
 image.Margin = new Thickness(5);                 
 var tt = new ToolTip();                 
 tt.Content = movie.Title;                 
 image.ToolTip = tt;                 
 var url = movie.Url;                 
 image.MouseDown += (sender, e) => System.Diagnostics.Process.Start(url);                 
 resultsPanel.Children.Add(image);             
 }         

Metot içerisinde gelen her bir Movie nesne örneği için bir BitmapImage yaratılmakta ve daha sonra arayüzdeki panel içerisine yaratılan Image’lar teker teker eklenmektedir. Netflix’e istekte bulunan QueryMovies metodu ise şu şekilde olacaktır.

Movie[] QueryMovies(int year, int first, int count)         
{             
 var client = new WebClient();             
 var url = String.Format(query, year, first, count);             
 var data = client.DownloadString(new Uri(url));             

 var movies =from entry in XDocument.Parse(data).Descendants(xa + "entry")                 
 let properties = entry.Element(xm + "properties")                 
 select new Movie                 
 {                     
 Title = (string)entry.Element(xa + "title"),
                  Url = (string)properties.Element(xd + "Url"),
 BoxArtUrl = (string)properties.Element(xd + "BoxArt").Element(xd + "LargeUrl")                 
 };
              return movies.ToArray();         

Yazımız boyunca en çok değineceğimiz metodumuz QueryMovies metodu olacaktır. Çünkü senkron veya asenkron geliştirmenin başlayacağı nokta bu metoddur. Biz ilk olarak senkron bir şekilde çalışacak uygulama geliştireceğimiz için, WebClient tipi içerisinde bulunan DownloadString metodunu kullandık. Bu metot senkron olarak ilgili adrese gitmekte ve o anda istekte bulunan threadi bekletmektedir. Bu nedenle uygulamayı tamamlayıp çalıştırdığımızda göreceksiniz ki filmlerin yüklenmesi hem uzun sürecek hem de bu sırada uygulamanız responsive(cevap verebilir) olmayacaktır.

Şimdi son olarak search butonumuz için Click olay metodunu da (event handler’ını da) yazalım ve uygulamamızı çalıştıralım.

private void btnSearch_Click(object sender, RoutedEventArgs e)         
{             
 LoadMovies(Int32.Parse(txtMovieYear.Text));         
} 

Uygulamayı çalıştırdığınızda istediğiniz bir yılı girip arama yapmaya çalıştığınızda Ara butonuna basar basmaz uygulamanızın kilitlendiğini göreceksiniz. Tabi network bağlantınıza göre uygulamanın yaklaşık olarak 1 ile 2 dakika arasında cevap veremez durumda olması hiçte istenilen bir durum değildir !  Hele ki artık uygulamaların tabletlere taşınmasıyla beraber bu gibi durumlar kullanıcı deneyimi açısından bakıldığında oldukça kötü deneyimler doğurmaktadır.

Özellikle uygulamalarınızda yukarıdaki örneğimizdeki gibi network üzerinden çağrılar yapıyorsanız veya I/O işlemleri gibi uzun sürebilecek işlemler gerçekleştiriyorsanız yapmanız gereken bu işlemleri asenkron bir biçimde gerçekleştirmektir. Böylece çalışan ana threadi kilitlemeyerek işlemleri bir arka thread’e alacağız.

Şimdi gelin aynı uygulamayı asenkron bir biçimde çalışacak şekilde değiştirelim. Bu değiştirme sırasında C# 5.0 ile gelen asenkron programlama yeniliklerini değil elimizde mevcut olarak bulunan asenkron yapılarını kullanacağız. Böylece C# 5.0 ile beraber gelen yeniliklerin kıymetini daha da iyi anlayacağız. ;)

C# 5.0 Öncesi Asenkron Programlama

.NET Framework içerisindeki kütüphanelere baktığımızda, bazıları içerisinde işlemlerin asenkron olarak yapılmasını sağlayan metotlar bulunduğunu görürüz. Bu fonksiyonlar Async son eki ile bitmektedir. Hatta web servis referansı eklediğinizde, eğer asenkron metotların da eklenmesini seçerseniz adları Async ile biten ve asenkron olarak çalışan metotları görebilirsiniz.

Şu anda framework içerisinde bulunan asenkron metotların çalışması ise callback mantığına dayanmaktadır. İlgili metodu çağırmadan önce metodun çalışmasının sonlanmasından sonra çalışacak olan bir callback tanımlıyorsunuz. Daha sonrasında ise metot arka planda işlemlerini sürdürürken ana threadiniz kilitlenmiyor ve uygulamanız tepki verebilir durumda kalıyor. Metot çalışması sonlandıktan sonra da callback fonksiyonu çalışarak ilgili işlemlerinizi yapabiliyorsunuz.

Bizim yukarıda çağırmış olduğumuz DownloadString metodunun da .NET Framework içerisinde asenkron olarak çalışan DownloadStringAsync isimli versiyonu bulunmaktadır. Şimdi gelin QueryMovies isimli metodumuzu bu noktadan başlayarak değiştirelim.

void QueryMoviesAsync(int year, int first, int count, 
 Action<Movie[], Exception> processMovies)         
{             
 var client = new WebClient();             
 var url = String.Format(query, year, first, count);             
 client.DownloadStringCompleted += (sender, e) =>             
 {                 
 if (e.Error != null)                 
 {                     
 processMovies(null, e.Error);                     
 return;                 
 }                 
 var data = e.Result;                 

 var movies = from entry in XDocument.Parse(data).Descendants(xa + "entry")                     
 let properties = entry.Element(xm + "properties")                     
 select new Movie                     
 {                         
 Title = (string)entry.Element(xa + "title"),                         
Url = (string)properties.Element(xd + "Url"),                         
 BoxArtUrl = (string)properties.Element(xd + "BoxArt").Element(xd + "LargeUrl")                     
 };                 
 processMovies(movies.ToArray(), null);             
 };             

 try             
 {                 
 client.DownloadStringAsync(new Uri(url));             
 }             
 catch (Exception ex)             
 {                 
 processMovies(null, ex);             
 }         
}

Gördüğünüz gibi öncelikle DownloadStringCompleted isimli DownloadStringAsync isimli metodun çalışmasının sonlanmasının ardından çağrılacak olan callback tanımını yaptık. Sonrasında ise DownloadStringAsync isimli metodu çağırdık.

Metotta yaptığımız değişikliklerden birisi de parametre olarak aldığımız processMovies isimli Action tipi. Bu Action delegate’i içerisinde ise Netflix servisine yapacağımız çağrıları tutuyor olacağız. Böylece her callback içerisinde ilgili çağrım kontrolleri yapılıyor olacak. QueryMoviesAsync metodunu çağırdığımız ve action tipindeki delegate’I parametre olarak geçirdiğimiz LoadMoviesAsync metodu ise şu şekilde olacaktır.

void LoadMoviesAsync(int year)         
{             
 resultsPanel.Children.Clear();             
 var pageSize = 10;             
 var imageCount = 0;             
 Action<Movie[], Exception> action = null;             
 action = (movies, ex) =>             
 {                 
 if (ex != null)                 
 {                     
 throw ex;                 
 }                 
 if (movies.Length > 0)                 
 {                     
 DisplayMovies(movies);                     
 imageCount += movies.Length;                     
 QueryMoviesAsync(year, imageCount, pageSize, action);                 
 }             
 };             
 QueryMoviesAsync(year, imageCount, pageSize, action);         
}

Şimdi uygulamayı çalıştırdığımızda ilk farkedeceğimiz değişiklik artık yılı girip ara butonuna bastığımızda uygulamanın kilitlenmeyeceğidir. Ayrıca uygulama asenkron olarak çalışacağından her 10’arlı grup çağrısında dönen filmler ekranda görünüyor olacaktır. Aslında baktığımızda yazımızın başında bahsettiğimiz kullanıcı deneyimi konusunda oldukça iyi bir ilerleme kaydettik.

Şimdi developer açısından baktığımızda, bakarsak senkron olarak yazdığımız kodu neredeyse tamamen değiştirdiğimizi görebiliriz. Bunun yanında yaptığımız callback tanımlamaları da metodumuzu oldukça uzattı. Eğer Netflix servisi filmlerin  fotoğraflarını, detaylarını ve film listesini ayrı bir adresten sunsaydı, yazacağımız metot taslak olarak şu şekilde olacaktı.

WebClient filmClient = new WebClient();             
filmClient.DownloadStringCompleted += (sender, e) =>                 
{                     
 WebClient imageClient = new WebClient();                     
 imageClient.DownloadStringCompleted += (_sender, _e) =>                         
 {                             
 WebClient detailClient = new WebClient();                             
 detailClient.DownloadStringCompleted += (__sender, __e) =>                                 
 {                                 
 };                             
 detailClient.DownloadStringAsync(new Uri("Detail Getirme URI'si"));                         
 };                     
 imageClient.DownloadStringAsync(new Uri("Image Getirme URI'si"));                 
};
             
filmClient.DownloadStringAsync(new Uri("Film Listesi Getirme URI'si"));

Gördüğünüz gibi asenkron çağrılarımız arttıkça callback’lerimizin de sayısı artmaktadır. Bu durum da metot içeriklerinin oldukça büyümesine ve metotlar üzerinde kontrolü kaybetmemize sebep olarak bakımı oldukça zorlaştırmaktadır.

Ayrıca bir uygulamadaki bazı kısımları asenkron çalıştırmak için neredeyse tüm kodu değiştirdik. Daha da önemli olan uygulama geliştirme mentalitemizi değiştirdik. Açıkcası asenkron uygulama geliştirirken Dekleratif Programlama(bir işi yaparken nasıl yapacağından çok ne yapacağına odaklanmak)’dan oldukça uzaktaydık. Bu noktada sanırım asenkron kod yazmak bu kadar zor olmamalıydı dediğinizi duyar gibiyim :) Öyleyse gelin artık C# 5.0 tarafına geçelim ;)

C# 5.0 ile Asenkron Programlama

C# 5.0’ın teması önceki yazımızda da bahsettiğimiz gibi asenkron programlama. Bu sürümle beraber asenkron işlemlerin orkestrasyonunun artık compiler tarafına bırakılması amaçlanmakta. Böylece de artık senkron ile asenkron programlama arasındaki development farkının minimuma indirilmesi hedeflenmekte. Peki nasıl mı ?

C# 5.0 ile beraber artık hayatımıza async ve await isminde iki keyword giriyor olacak. Bu keywordlerden ilki olan async, asenkron çağrı yapılan metotların işaretlenmesi amacıyla kullanılmaktadır. Eğer bir metodunuz içerisinde asenkron bir çağrıda bulunuyorsanız ve bu çağrıdan dönen sonucun uygulama tarafına dönme işlemlerini compiler tarafına bırakmak istiyorsanız o metodun başına async keywordünü koymanız gerekmektedir. Böylece compiler async keywordünü gördüğü metotlarda asenkron çağrı yapıldığını algılayıp, çağrı yapılan yerlerde gerekli yapıları ve işleri kendisi arka planda yaratmaktacak ve yürütmektecektir.

Await keyword’ünü ise asenkron işlemleri çağırma sırasında kullanmaktayız. Asenkron çağrının yapıldığı kısımda await kullanarak bu ifadenin devamında bulunan kod bloğunun asenkron işlemin sonucunda işletilecek bölüm olduğunu compilera belirtmekteyiz.

Şimdi yavaş yavaş C# 5.0 ’a giriş yapalım. İlk olarak yapmamız gereken şu anda CTP3 sürümünde olan Visual Studio Async’i kurmak. Buradaki adresten ilgili setup dosyasını indirip kurulumu yapmanız gerekmekte. Kurulumu yaptıktan sonra çeşitli platformlardaki uygulamalarınızda kullanmanız için gelen farklı kütüphaneleri Documents\Microsoft Visual Studio Async CTP\Samples klasörü içerisinde bulacaksınız. Biz .NET uygulamalarında kullanacağımız AsyncCtpLibrary.dll’ini projemize öncelikle referans olarak ekliyor olacağız.

İlk olarak değişikliğimize WebClient tipi içerisinde bulunan DownloadStringAsync metodu ile başlayacağız. Yukarıda bahsetmiş olduğum kütüphaneyi proje referans olarak eklediyseniz WebClient tipi içerisine Task<string> tipini döndüren DownloadStringTaskAsync isimli metodun extension metot olarak eklendiğini görebilirsiniz. Peki bu metodun anlamı ne ?

Task tipi bildiğimiz gibi .NET 4.0 ile beraber paralel programlama yenilikleri kapsamında  .NET Framework içerisine eklendi. En basit anlamda söylememiz gerekirse Task tipi devam etmekte olan asenkron bir işlemi temsil etmektedir. Bu nedenle aslında baktığımızda Task tipi asenkron operasyonların yönetimi esnasında kullanılacak en öncelikli tiptir. İşte bu sebepten dolayı await ifadesi Task tipi veya void dönüş tipine sahip işlemler ile kullanılabilmekte yani compiler Task,Task<T> veya void dönüş değerine sahip asenkron işlemlerin yönetimini yapabilmektedir.

async Task<Movie[]> QueryMoviesAsync(int year, int first, int count)         
{             
 var client = new WebClient();             
 var url = String.Format(query, year, first, count);             
 var data = await client.DownloadStringTaskAsync(new Uri(url));             
 var movies =from entry in XDocument.Parse(data).Descendants(xa + "entry")                 
 let properties = entry.Element(xm + "properties")                 
 select new Movie                 
 {                     
 Title = (string)entry.Element(xa + "title"),                     
 Url = (string)properties.Element(xd + "Url"),                     
 BoxArtUrl = (string)properties.Element(xd + "BoxArt").Element(xd + "LargeUrl")                 
 };             
 return movies.ToArray();         

Yukarıda QueryMovies metodumuzun C# 5.0 ‘a göre güncellenmiş halini görmekteyiz. İlk olarak yukarıda bahsettiğimiz gibi WebClient tipinin DownloadStringTaskAsync metodunu kullandık. Daha sonra bu metodu çağırmadan önce await keywordünü kullanarak bu metot çağrımından sonra bulunan ifadelerin artık callback içerisinde bulunmasını ve asenkron işlem tamamlandıktan sonra işletilmesi gerektiğini compilera belirttik.

Daha sonra ise metodumuz içerisinde asenkron bir çağrımda bulunduğumuzdan dolayı QueryMovies isimli metodun başına async modifier’ını koyduk. Böylece compilera bu metot içerisinde asenkron bir çağrım olduğunu ve await ifadesi gördüğü kısımlarda gerekli işlemleri yapmasını bildirdik.

Son olarak ise metodumuzun dönüş tipini Task<Movies[]> şeklinde değiştirdik. Böylece LoadMovies metodu içerisinden asenkron olarak bu metodun çağrımını gerçekleştirebileceğiz. Metodumuzun ismininde QueryMoviesAsync olarak değiştiğini farketmişsinizdir. Bunun nedeni ise isimlendirme kurallarına uygun bir şekilde geliştirme yapmamızdır. Asenkron olarak çalışan metotların isimlerinin sonuna Async koyarak bu metotları kullanan diğer developerların da metodun asenkron olarak çalıştığını anlaması kolaylaşacaktır.

Şimdi gelelim LoadMovies isimli metodumuza. Aslında bu metodumuz üzerinde de hemen hemen yukarıda yapmış olduğumuz değişiklikleri yapıyor olacağız.

async void LoadMoviesAsync(int year)         
{             
 resultsPanel.Children.Clear();             
 var pageSize = 10;             
 var imageCount = 0;             
 while (true)             
 {                 
 var movies = await QueryMoviesAsync(year, imageCount, pageSize);                 
 if (movies.Length == 0) break;                 
 DisplayMovies(movies);                 
 imageCount += movies.Length;             
 }         

Yukarıda gördüğünüz gibi kodumuz aslında neredeyse senkron kod ile aynı. Sadece metodumuzun başına async modifierını koyduk ve metot içerisinde bir asenkron metot çağrımı olacağını compiler’a bildirdik. Daha sonra ise biraz önce yazmış olduğumuz QueryMoviesAsync metodunu çağrımından önce await kullanarak metot çağrımından sonra gelen ifadelerin artık metot işletiminden sonra işletilmesi gerektiğini compilera bildirdik. Bir de tabi ki yine asenkron çalışan bir metot geliştirdiğimiz için metodumuzun ismini LoadMoviesAsync olarak değiştirdik.

Async & Await ile Kolaylaşan Asenkron İşlemler

Evet arkadaşlar gördüğünüz gibi C# 5.0 ile beraber gelen async ve await modifierları ile artık senkron veya asenkron çalışan kodlar arasında çokta fazla fark kalmıyor. Hemen hemen 2-3 değişiklik ile senkron olarak çalışan kodumuzu asenkron olarak çalışacak duruma getirebiliyoruz. Aşağıdaki görsellerde şimdiye kadar yazmış olduğumuz senkron, asenkron ve C# 5.0 asenkron kodlarını ve aralarındaki farklılıkları görebilirsiniz.

C# 5.0’ın temasının asenkron programlamayı senkron programalama kadar basit yapmak olduğunu yeniden hatırlarsak bunu başarıyla gerçekleştirdiğiniz sanırım yukarıdaki tablodan çıkarabiliriz.

Asenkron programlama yeniliklerini özetlememiz gerekirse;

Temel olarak C# 5.0 ile dile async ve await keywordleri gelmektedir. Bu keywordlerden async bir metot modifier olarak kullanılırken yazmış olduğunuz  metot içerisinde asenkron bir işlem yapıldığını compilera bildirmekte. async modifier’ına sahip olan metotların dönüş tiplerinin void,Task veya Task<T> tiplerinden birinin olması gerektiğini aklımızda bulundurmamızda yarar var.

Await ifadesi ise asenkron yürütülecek olan bir işlemin compilera bildirilmesinde ve bu ifadenin altında bulunan ifadelerin asenkron işlemin sonucunda işletileceğini compilera bildirmekte. Böylece compiler arka planda kurduğu callback yapısına bizim kodlarımızı dahil etmekte.

Bu noktaya kadar farkettiyseniz .NET 4.5 ile beraber gelecek olan hiçbir tipten bahsetmedik. Bunun nedeni ise C# 5.0’ın tamamen .NET Framework içerisinde bulunan mevcut tipleri kullanarak tüm iş yükünü üzerine alması. Belki de bu gelen yeni özelliğin bir dil özelliği olduğunu en iyi açıklayan argümanımız bu ;)

C# 5.0 ile gördüğünüz gibi yine oldukça güzel özellikler gelmekte. Async özelliğinin yukarıda bahsetmiş olduğumuz kullanımı dışında daha farklı kullanımlarını da ilerleyen yazılarımızda inceliyor olacağız. Bir sonraki yazımızda görüşmek üzere, C# ile kalın… Not 1: Uygulama Visual Studio Async CTP3 ile geliştirilmiştir. Yazımız boyunca yazdığımız C# kodlarını aşağıdan indirebilirsiniz. AsyncStuff


Yorum Gönder


Yorumlar

  • profile

    Ender

    • 22
    • 4
    • 2013

    Merhaba, Açıklayıcı paylaşımınız için teşekkürler. Buarada Netflix api kurallarını değiştirmiş 8 nisan 2013 tarihinde ve program o yüzden hata vermektedir. Ben yeni api adresini ve okumayı bulursam eklerim.