• Anasayfa
  • Hakkımızda
  • Etkinlikler
  • Destek Verin
  • Site Haritası
  • Giriş Yap
  • Üye Ol
  • Facebook
  • Twitter
  • RSS
Yazılım Dilleri
  • Soru - Cevap
  • EĞİTİM SETİ
  • KATEGORİ
  • DUYURU
  • TEKNOLOJİ HABERLERİ

Son Sorular

  • 23.04.2016 00:55:33C programlama 2 oyun
  • 20.04.2016 16:34:41Local Database
  • 15.04.2016 14:26:15Fatura kayıt işlemi
  • 21.03.2016 01:55:30C# problem

Popüler Sorular

  • 27.05.2012 05:49:50Asp.Net ile Date time alana veri ekleyemiiyorum ?
  • 2.04.2012 00:45:18.exe uzantılı dosya için dijital imza nerde nasıl alınır.
  • 12.05.2012 08:44:49Acil Yardım
  • 27.05.2012 13:46:51veri tabanı bağlantısı
  • .Net Framework
  • 8085 Assembly
  • Active Directory
  • ADO.NET
  • Android
  • Apple IOS
  • Arduino
  • ASP.NET
  • ASP.NET MVC
  • Blackberry
  • C#.Net
  • C++
  • CCG Framework
  • CISCO
  • CSS
  • Diğer
  • Dreamweaver
  • Entity Framework
  • Exchange Server
  • Gömülü Sistemler
  • GSM Programlama
  • Güncel
  • Güvenlik
  • HTML5
  • Java
  • Javascript / JQuery
  • Jira
  • Kariyer ve İş Yaşamı
  • LINQ
  • LibreOffice
  • Linux
  • Matlab
  • Microsoft Dynamics CRM
  • Mobil Uygulama Geliştirme
  • MySQL
  • NoSQL
  • Oracle
  • OWIN
  • PFSense
  • PHP
  • Powershell
  • Python
  • Sanallastirma
  • SAP-ABAP
  • SCOM 2012
  • SEO
  • Sharepoint 2010
  • Sharepoint 2013
  • Silverlight
  • Sistem Analiz ve Tasarımı
  • SQL Server
  • Symantec
  • TFS
  • T-SQL
  • Ubuntu
  • VB.NET
  • Veritabanı Yönetim Sistemleri
  • Visual Studio
  • VMware
  • WCF
  • Web Hosting
  • Windows 8
  • Windows Azure
  • Windows Phone 7.1
  • Windows Phone 8
  • Windows Server
  • Wordpress
  • WPF
  • Xamarin
  • XNA
  • Yazılım Mühendisliği
  • Yöneylem Araştırması
  • ASP.NET MVC
  • Entity Framework
  • Javascript / JQuery
  • LINQ
  • PHP

Son Duyurular

IPhone 6 ve IPhone 6 Plus Teknik Özellikleri ve Fiyatı

IPhone 6 ve IPhone 6 Plus Teknik Özellikleri ve Fiyatı

DELL'in Yeni Projesi: USB Bilgisayar (Project Ophelia)

DELL'in Yeni Projesi: USB Bilgisayar (Project Ophelia)

Windows Phone Youtube Uygulaması Google ve Microsoft ile Yeniden Yapılıyor

Windows Phone Youtube Uygulaması Google ve Microsoft ile Yeniden Yapılıyor

Android ve Apple IOS Telefonlar için Blackberry Messenger (BBM)

Android ve Apple IOS Telefonlar için Blackberry Messenger (BBM)

Nokia Lumia 925 Teknik Özellikleri, Lumia 928 ve 920 ile Karşılaştırması

Nokia Lumia 925 Teknik Özellikleri, Lumia 928 ve 920 ile Karşılaştırması

LG Optimus G Pro Özellikleri ve Gözle Video Oynatma Teknolojisi

LG Optimus G Pro Özellikleri ve Gözle Video Oynatma Teknolojisi

WCF Tarafında Task Bazlı Asenkron Operasyonlar

WCF Tarafında Task Bazlı Asenkron Operasyonlar

23.08.2012

Yazar: Burak Selim Şenyurt (Google+)

Kategori: WCF

2168

 Merhaba Arkadaşlar,

Yandaki karikatür, aşağıdaki yazıyı bitirdiğim zaman aradığım giriş resmi ile ilişkili olarak karşıma çıkan örneklerden sadece bir tanesiydi. Beni epey bir güldürdüğünü ve neşelendirdiğini ifade edebilirim Laughing Konumuz işlerimizi birilerine yönlendirip yan gelip yatmak değil elbette, ama ona benzer olduğunu ifade edebilirim.

Bu adamın görevlerini başkaların atadıktan sonra, söz konusu işler yapılırken başka işlere(örneğin koltuğunda şöyle bir geriye doğru yaslanarak vakit geçirmek) yönelebildiğine odaklanmaya çalışalım..Net Framework tarafındaki Delegate tipleri de benzer bir ihtiyacı karşılamıyor mu? Wink Asenkron olarak fonksiyonların çağırılabilmesini sağlamak(Elbette başka yetenekleri de var ama bu en önemlileri arasında sayılabilir)

Uzun bir zamandır .Net Framework içerisinde, fonksiyonların asenkronize edilmesi üzerinde çalışılmaktadır. Daha önceleri Thread bazlı veya Delegate tipleri ile gerçekleştirdiğimiz asenkron çağırımlar, .Net Framework 4.0’ a gömülü olarak gelen Task Parallel Library sayesinde daha da gelişmiş ve alt yapının her noktasına enjekte edilebilir olmuştur. Şu günlerde .Net Framework 4.5ile birlikte gündeme gelen ve uzun zamandır da haberdar olduğumuz async, await gibi anahtar kelimeler de, temel de Task tiplerine dayanmaktadır. Bir başka deyişle TPL kütüphanesi ve içeriği, ilerleyen zamanlarda .Net Framework’ ün pek çok önemli alt yapısında etkisini hissettirecektir.

Bu yazımızda Task tiplerinden yararlanarak, WCF(Windows Communication Foundation)servislerinde asenkron operasyon tanımlamalarının nasıl yapılabileceğini ve incelemeye çalışıyor olacağız. Gerçekleştirmeyi planladığımız işlemlerde önemli olan nokta ise, asenkron yürütmelerinistemci(Client) tarafında değil, servis tarafındaki operasyonlar için söz konusu olmasıdır. Bir başka deyişle eş zamanlı olarak çalışabilen(Concurrent) servis operasyonlarının, Task tiplerinden yararlanarak nasıl asenkron hale getirilebileceğini görmeye çalışacağız. Elbette bu asenkronize edilmiş metodlar servis tarafında değerlendirilen bir yaklaşımı içerecektir.

Aslında bir servis operasyonunun asenkron çalışacak hale getirilmesi, delegate tipleri ile kullanabildiğimiz(hatta Ado.Net 2.0’ dan bu yana pek çok XCommand gibi tipinde var olan) Begin… ve End… ön ekli metod oluşumlarının uygulanmasından ibarettir. Aşağıdaki örnek kod parçasında sadece hatırlatıcı olması açısından bir Delegate tipi üzerinden ilgili BeginInvoke ve EndInvokemetodlarına nasıl ulaşılabildiği gösterilmeye çalışılmıştır. Örnekte Async Callback modeli değerlendirilmiştir. Bir başla deyişle asenkron olarak başlatılan metod işleyişini tamamladığında, uygulama ortamındaki başka bir geri bildirim fonksiyonu tetiklenmektedir.

using System; 
using System.Collections.Generic;

namespace AzonTestClient 
{ 
    // Örnek bir generic temsilci 
    delegate int SaveToFileDelegate<T>(IEnumerable<T> list);

    class Program 
    { 
        static void Main(string[] args) 
        { 
            #region Async Callback modeli

            // Temsilci örneklenir 
            SaveToFileDelegate<object> dlg=new SaveToFileDelegate<object>(SaveToFile); 
            // BeginInvoke çağrısı ile dlg' nin işaret ettiği SaveToFile metodunun çağırılması ve kodun ifade sonundan itibaren akmaya devam etmesi sağlanır 
            // ilk parametre SaveToFile metodunun alacağı değişken, ikinci parametre işlem bittiğinde tetiklenecek geri bildirim fonksiyonunun işaretçisi olan temsilci, üçüncü parametre ise geri bildirim metodunda AsyncState özelliği üzerinden yakalanacan Delegate referansı 
            IAsyncResult asyncResult = dlg.BeginInvoke(new List<object>(), new AsyncCallback(Callback), dlg); 
            // akış buradan kesilmeden devam eder

            #endregion

            Console.ReadLine(); 
        }

        // Uzun süreli işlem içeren örnek metod 
        static int SaveToFile<T>(IEnumerable<T> list) 
        { 
            //TODO: Çok büyük boyutlu bir veri içeriğinin dosyaya yazılması söz konusudur. Zaman alan bir işlem olarak düşünülebilir 
            return 1; 
        } 
        // Async Callback tekniğine göre SaveToFileDelegate<T> ile işaret edilen metod sonlandığında devreye girecek olan geri bildirim fonksiyonu 
        static void Callback(IAsyncResult asyncResult) 
        { 
            // EndInvoke çağrısı ile ilişkili olan delegate tipi yakalanır 
            var dlg = asyncResult.AsyncState as SaveToFileDelegate<object>; 
            // delegate tipi üzerinden EndInvoke çağrısı yapılarak SaveToFile metodunun sonucu alınır 
            int result = dlg.EndInvoke(asyncResult); 
            // Sonuç değerlendirilir 
        } 
    } 
}

Delegate tiplerinin kullanımı göz önüne alındığında, Polling, Callback, WaitHandle gibi modelleri destekleyebilen BeginInvoke ve EndInvoke metod çağırımlarının söz konusu olduğu bilinmektedir. BeginInvoke metodu IAsyncResult arayüzü(Interface) tipinden bir referans döndürmekte olup, program kod akışının izleyen satırdan devam edebilmesini sağlmaktadır. Pek tabi, EndInvoke metodu içerisinde de ilgili IAsyncResult arayüz referansından yararlanarak sonuçların alınması söz konusudur. Bu iki metod arasındaki çalışma süreci, ana sürece(varsayılan olarak uygulamanın Main Thread’ i olarak da düşünebiliriz) veya diğer süreçlere paralel olarak yürütülmektedir.

Dolayısıyla benzer bir yaklaşımı WCF servislerinde, asenkron hale getirilmek istenen operasyonlar için de düşünebiliriz. Gelin öncelikle senkron olarak uzun süren işlem içeren örnek bir WCF servisini geliştirelim. Bu amaçla aşağıdaki servis sözleşmesini(Service Contract) içeren bir servis uygulamasını göz önüne alabiliriz.

awcf_1

IProductService arayüz tipi(Interface);

using System.ServiceModel;

namespace AzonServices 
{ 
    [ServiceContract] 
    public interface IProductService 
    { 
        [OperationContract] 
        int CreateProducts(int totalProductCount); 
    } 
}

ProductService sınıfı;

using System; 
using System.Collections.Generic;

namespace AzonServices 
{ 
    public class ProductService 
       : IProductService 
    { 
        public int CreateProducts(int totalProductCount) 
        { 
            int createdProductCount = 0; 
            char[] classes = {'C', 'D', 'E', 'L', 'S'}; 
            List<Product> products = new List<Product>(); 
            Random randomizer = new Random();

            for (int i = 0; i < totalProductCount; i++) 
            { 
                Product newProduct = new Product 
                                         { 
                                             ProductId=i, 
                                             Name="PRD-"+i.ToString(), 
                                             ListPrice=randomizer.Next(1,100), 
                                             StockSize=randomizer.Next(50,500), 
                                             Class=classes[randomizer.Next(0,classes.Length)] 
                                         }; 
                products.Add(newProduct); 
                createdProductCount++; 
            } 
            //TODO: product listesinin veritabanın yazılma veya dosyaya kayıt edilme işlemi yapılacak 
            return createdProductCount; 
        } 
    } 
}

Product POCO sınıfı;

namespace AzonServices 
{ 
    class Product 
    { 
        public char Class { get; set; } 
        public int StockSize { get; set; } 
        public int ListPrice { get; set; } 
        public string Name { get; set; } 
        public int ProductId { get; set; } 
    } 
}

CreateProducts metodu istemciden aldığı toplam miktara göre bir Product listesi üretmektedir. Test amaçlı olarak üretilen bu listenin içerisinde yer alan ürün bilgileri, rastgele değerlerden oluşmaktadır. İstemcinin vereceği maksimum ürün sayısına göre ilgili operasyonun uzun sürmesi olasıdır. İstemci açısından bakıldığında, söz konusu operasyonunun tamamlanana kadar uygulama içerisinde beklenmesine gerek yoktur. Bu, zaten istemci tarafında sahip olduğumuz ilgili servisi asenkron olarak çağırma yeteneğidir. Hatta servisi istemci tarafına eklerken Add Service Reference arabirimindeki ilgili opsiyon etkinleştirilerek servis operasyonlarının olay bazlı(Event Based) asenkron çağırım versiyonlarının üretilmesi sağlanabilmektedir.

İstemci tarafında servis çağırımlarına ait asenkron operasyon desteğini etkinleştirmek için, Generate asynchronous operations özelliğinin işaretlenmiş olması gerekmektedir.

awcf_2

Sonuç olarak üretilen Async uzantılı asenkron çağırım metodu ve servis operasyon işleminin tamamlanması sonrası devreye girecek fonksiyonu işaret edecek olan olay(Event), kod tarafında değerlendirilebilir olacaktır.

awcf_3

Gayet güzel Wink Buraya kadar ki kısımda zaten pek bir sıkıntı yok açıkçası. Ancak şöyle bir durum da söz konusu,

Servise eş zamanlı olarak gelen çağrılarda ve tek bir servis örneğinin(Instance) oluşmasının tercih edildiği durumlarda, servis üzerindeki bu yük nasıl asenkronize edilebilir?

İşte yazımızın asıl konusu da budur.

Başlarda da belirttiğimiz gibi servis tarafında IAsyncResult arayüzü ve Task tiplerini kullanarak, eş zamanlı(Concurrent) olarak gelen çağrılarda, ilgili operasyonların servis tarafını gereksiz yere duraksatması engellenebilir. Bunun için IProductService servis sözleşmesini(Service Contract)ve ProductService sınıfını aşağıdaki gibi değiştirmemiz yeterli olacaktır.

Önce Class Diagram üzerinden ilgili değişikliklere bir bakalım.

awcf_4

IProductService arayüzünün yeni versiyonu;

using System.ServiceModel; 
using System;

namespace AzonServices 
{ 
    [ServiceContract] 
    public interface IProductService 
    { 
        [OperationContract(AsyncPattern=true, Action="CreateProducts", Name="CreateProducts", ReplyAction ="CreateProductsReply")] 
        IAsyncResult BeginCreateProducts(int totalProductCount,AsyncCallback callback,object asyncState);

        int EndCreateProducts(IAsyncResult result); 
    } 
}

Servis sözleşmesinde Begin ve End ön ekleri ile başlayan iki metod yer almaktadır. Dikkat edilmesi gereken noktalardan birisi, EndCreateProducts metodunun OperationContractniteliği(Attribute) ile imzalanmamış oluşudur. Nitekim bu metod, BeginCreateProductsmetodunun tamamlanması sonucu devreye giren metod olmakla birlikte, sadece servis tarafını ilgilendiren bir fonksiyondur. Dolayısıyla istemci tarafına açılmasına söz konusu değildir.

BeginCreateProducts metoduna ait OperationContract niteliğinde ise bazı özellikler set edilmiştir. Herşeyden önce ilgili operasyonun Asenkron desene uygun olarak çalışacağının belirtilmesi gerekmektedir. Bu amaçla AsyncPattern özelliğine true değeri verilmiştir. Diğer taraftan aksiyon, operasyonun istemci tarafından görünecek olan adı ve istemci tarafında verilecek olan cevaba ait Action bilgisi de ilgili özelliklerce set edilmiştir.

BeginCreateProducts metodu ve EndCreateProducts metodlarının şema yapılarına bakıldığında,temsilci(Delegate) tiplerinin BeginInvoke ve EndInvoke metodlarından farksız oldukları gözlemlenmektedir. (İsimlendirme standartdını bozmamak açısından da bu şekilde bir adlandırma tercih edilmelidir) 

BeginCreateProducts metodu, ilk parametre olarak istemciden gelecek olan integer değeri almaktadır. Son iki parametre ise değişmez sırada olmalıdır. Bunlardan birisi Callback metodunu işaret edecek olan AsyncCallback temsilcisi iken, son parametre de EndCreateProducts metodu içerisinde BeginCreateProducts fonksiyonunda başlatılan Task örneğini yakalamak ve dolasıyıyla sonucunu almak üzere kullanılan object referansıdır.

ProductService sınıfının yeni versiyonu;

using System; 
using System.Collections.Generic; 
using System.ServiceModel; 
using System.Threading.Tasks;

namespace AzonServices 
{ 
    [ServiceBehavior(InstanceContextMode= InstanceContextMode.Single, ConcurrencyMode= ConcurrencyMode.Multiple)] 
    public class ProductService 
        : IProductService 
    { 
        public IAsyncResult BeginCreateProducts(int totalProductCount, AsyncCallback callback, object asyncState) 
        { 
            var task = new Task<int>((s) => 
                                         { 
                                             int createdProductCount = 0; 
                                             char[] classes = {'C', 'D', 'E', 'L', 'S'}; 
                                             List<Product> products = new List<Product>(); 
                                             Random randomizer = new Random();

                                             for (int i = 0; i < totalProductCount; i++) 
                                             { 
                                                 Product newProduct = new Product 
                                                                          { 
                                                                              ProductId = i, 
                                                                              Name = "PRD-" + i.ToString(), 
                                                                              ListPrice = randomizer.Next(1, 100), 
                                                                              StockSize = randomizer.Next(50, 500), 
                                                                              Class = 
                                                                                  classes[ 
                                                                                      randomizer.Next(0, classes.Length) 
                                                                                  ] 
                                                                          }; 
                                                 products.Add(newProduct); 
                                                 createdProductCount++; 
                                             } 
                                             return createdProductCount; 
                                         }, asyncState);

            task.ContinueWith((t) => { callback(t); }); 
            task.Start();

            return task; 
        }

        public int EndCreateProducts(IAsyncResult result) 
        { 
            var task = (Task<int>) result; 
            return task.Result; 
        } 
    } 
}

ProductService tipinin ilk dikkat çeken noktalarından birisi, ServiceBehvaior niteliğinde set edilen özelliklerdir. Servisin bellek üzerinde tek bir örnek olarak oluşturulması belirlendikten sonra(InstanceContextMode.Single), servis operasyonlarında Async değeri true olanlara da eş zamanlı olarak erşilebileceği ifade edilmektedir(ConcurrencyMode.Multiple)

BeginCreateProducts metodunun içerisinde Task tipinden yararlanıldığı görülmektedir. Asenkronolarak yürütülmek istenen operasyona ait kod parçaları Task tipi örneklenirken ilgili isimsiz metod(Anonymous Method) içerisine yazılmıştır. Bu örnekte Task tipinin generic bir versiyonun kullanıldığı görülmektedir. Nitekim metod geriye int tipinden bir sonuç döndürecek şekilde tasarlanmıştır. Task tipinin örneklenmesi sırasında kullanılan asyncState nesne örneğiEndCreateProducts metodu içerisinde yakalanacak olan Task nesne örneğine ait referans olacaktır.

İlerleyen satırlarda task nesne örneğinin tamamlanması sonucu callback değişkeni ile ifade edilen çalışma zamanı metodunun tetiklenmesi ve t isimli Task değişkeninin(ki bu t, task isimli değişkeni ifade etmektedir) ilgili geri bildirim metodunun(ki EndCreateProducts olmaktadır) IAsyncResultarayüzüne atanması sağlanır(ContinueWith kısmı). Start metodu ile bildiğiniz üzere ilgili task örneği başlatılmaktadır. Bundan sonraki aşama ise oldukçta basittir. EndCreateProducts metoduna gelecek olan IAsyncResult arayüzünden yararlanılarak çalışma zamanındaki Task<int> referansı yakalanmakta ve Result özelliği ile çalışma sonucu üretilen tamsayı değeri geriye, bir başka deyişle itemci tarafına döndürülmektedir.

Biraz karmaşık gözüken bir desen olduğunun farkındayım Undecided Ancak kalıp olarak düşünüldüğünde pek çok servis operasyonuna kolayca entegre edilebilecek bir yapı olarak düşünülebilir. Elbette bu konuyu bir de, .Net Framework 4.5’ e entegre olarak gelen yeni async ve await anahtar kelimelerini göz önüne alarak değerlendirmekte yarar vardır. Bunu da ilerleyen zamanlarda incelemeyi planlamaktayım Wink Böylece geldik bir yazımızın daha sonuna. Bir sonraki yazımızda görüşünceye dek hepinize mutlu günler dilerim.

AzonServices.zip (67,73 kb)

 

Yazar Hakkında

Burak Selim Şenyurt

Burak Selim Şenyurt

buraksenyurt.com

Yıldız Teknik Üniversitesi Matematik Mühendisliği mezunu olan Şenyurt, 1999 yılında profesyonel olarak adım attığı yazılım dünyasında, 2003 yılından beri Microsoft .Net teknolojileri ile ilgilenmektedir. Yazılım hayatına Assist Line isimli Call Center firmasında Delphi programcısı olarak başlayan Şenyurt sonrasında, sırasıyla Bizitek(Junior Developer), Netron(Master Trainer), Citibank(Outsource Senior Software Developer), Innova(Application Development Consultant), ve TCM(Software Architect) firmalarında görev almıştır. Su anda ING Bank bünyesinde Kıdemli Yazılım Danışmanı olarak görev yapmaktadir. 2006, 2007 yıllarında C#, 2008,2009,2010 yıllarında ise Connected System Developer kategorisinde Microsoft MVP seçilen Şenyurt, evli ve 1 çocuk babasıdır. C# diline olan düşkünlüğü, oğluna S(h)arp adının verilmesinde önemli bir etken olmustur.

Sosyal Medya

ORANLAR

  • 2168izleme

Arkadaşlarınla Paylaş

  • Tweet

0 Yorum

Yorum Yaz / Soru Sor

Lütfen yorum yazmak veya soru sormak için üye girişi yapınız.

Son Yorumlar

  • Hocam Link başka sayfaya yönlendiriyor.
  • merhaba benim merak ettiğim bir konu var y...
  • Merhaba download linki çalışmıyor. Rica et...
  • Nevzat Bey selamlar, Açıkçası bizler a...
  • Parametreleri Cache İşleminden Yalıtma kon...

En Güncel Sorular

  • Bilgilendirme maili (C#.Net)
  • Power Pivot (Sharepoint 2010)
  • BigInteger, BigDecimal (Asp.Net ve Asp.Net MVC)
  • visual C# ile asp nette veritabanı islemleri (Asp.Net ve Asp.Net MVC)
  • Share Point ile Dosya Arşiv Yönetim Sistemi yapılabilir mi ? (Sharepoint 2010)

En Son Cevap Verilen Sorular

  • Bilgilendirme maili
  • BigInteger, BigDecimal
  • visual C# ile asp nette veritabanı islemleri
  • Share Point ile Dosya Arşiv Yönetim Sistemi yapılabilir mi ?
  • txt dosyasına veri yazma

Twitter

Takip et: @yazilim_dilleri

En Çok Okunanlar

Elif BAYRAKDAR

C# ile SQL Server Bağlantısı, Insert, Update ve Delete Sorguları

23.05.2013

  • 121521
  • 0
Hakan Keskin

C# ile Windows Service Projesi Oluşturma, Debug Etme ve Setup Hazırlama

17.12.2013

  • 67179
  • 0
batuhan avlayan

Php - Mail Gönderme (İletişim Formu)

02.09.2013

  • 49424
  • 0

Sponsorlar

KODLAB
Pluralsight
Exchange server is
Office 365
YAZILIM DİLLERİ
Yukarı Çık
  • Hakkımızda
  • Facebook
  • Twitter
  • RSS

© Yazılım Dillerinin Buluşma Noktası | Kaynak belirtildiği sürece makaleler kopyalanabilir.
YazilimDilleri.Net sitesinde yer alan kullanıcıların oluşturduğu tüm içeriklerin yayınlanması ile ilgili yasal yükümlülükler içeriği oluşturan kullanıcıya aittir, YazilimDilleri.Net hiçbir şekilde sorumlu değildir.

Kapat

Giriş Yap

Kullanıcı Adı

Şifre

Şifremi Unuttum

KULLANICI GİRİŞİ