برنامه نویسی نامتقارن (Asynchronous) با استفاده از Delegates

پنجشنبه 21 آبان 1394

این مقاله به توضیح مفهوم برنامه نویسی asynchronous با استفاده از Delegates می پردازد. Delegates قابل استفاده در threading به خصوص برای عملیات Callback هستند . این شیوه قادر می سازد که asynchronous متد synchronous را صدا بزند.

برنامه نویسی نامتقارن (Asynchronous) با استفاده از Delegates

این مقاله به توضیح مفهوم برنامه نویسی asynchronous  با استفاده از DelegateS می پردازد.

Delegates قابل استفاده در threading به خصوص برای عملیات Callback هستند . این  شیوه  قادر می سازد که asynchronous  متد synchronous را صدا بزند.

پس از اتمام عملیات ، اطلاعات را گزارش می دهد.

Thread نیاز به یک اشاره گر دارد تا قادر به اجرای Callback باشد

Thread نمی تواند متد را صدا بزند برای  همین تابع  pointer مورد نیاز است. و اینجا Delegate به عنوان تابع pointer عمل میکند.

Threads میتواند به راحتی از Delegate یا anonymous method یا Lambda expression استفاده کند

در زیر رابطه اساسی Delegate با Thread یا Task را ببینید

شروع یک Task با Delegate

public void StartThreadWithDelegate()    
{    
    Task task = new Task(delegate { ShowInformation(); });    
    task.Start();    
}    
  
private void ShowInformation()    
{    
    Console.WriteLine("Thread Executed");    
}   

Thread با متد Anonymous

public void ThreadWithAnonymousMethod()    
{    
    new Thread(delegate()    
    {    
        ShowInformation();    
    }).Start();    
    new Thread(delegate()    
    {    
        ShowInformation();    
    }).Start();    
}   

Thread  با  Lambda Expression

public void ThreadWithLambdaExpression()    
{    
    new Thread(() =>ShowInformation()).Start();    
    new Thread(() =>ShowInformation()).Start();    
}   

توضیحات فوق اصول اولیه مربوط برای نوشتن Thread با استفاده از Delegate است . اما تمرکز اصلی ما در این مقاله توضیح الگوهای مختلف برای پیاده سازی و یا اجرای یک بخش از کد asynchronously با کمک Delegate می باشد.

در زیر روش های مختلف یا روش هایی برای اجرای asynchronously با استفاده از Delegate را میبینید

Callback 

Polling

EndInvoke

من میخواهم حالت asynchronous را با کمک Delegate یک به یک با جزییات توضیح دهیم

Callback  

Callback :  روشی که در ان یک قطعه و یا بخشی از یک کد است که به عنوان ارگومان به کد دیگر منتقل می شود.

در اینجا Thread عملیات Async را شروع می کند اما برای تکمیل عملیات صبر نمی کند

شامل فضای نام زیر میباشد

using System.Runtime.Remoting.Messaging;  

در زیر کد مثال را مشاهده کنید

public class CallBackOperation    
{    
    public delegate int MyCallBackOperationDelegate(int number, int numberOfTimes);    
  
    public static int MyMenthod(int number, int numberOfTimes)    
    {    
        for (int counter = 0; counter < 1000; counter++)    
        {    
            number = number + counter;    
        }    
  
        return number;    
    }    
  
    public static void MyCallBackOperation(IAsyncResult asyncResult)    
    {    
        AsyncResult myasyncResult = asyncResult as AsyncResult;    
        MyCallBackOperationDelegate myCallBackOperationDelegate = (MyCallBackOperationDelegate)myasyncResult.AsyncDelegate;    
        var result = myCallBackOperationDelegate.EndInvoke(asyncResult);    
  
        Console.WriteLine("Result : {0}", result);    
    }    
  
}   
static void Main(string[] args)    
{    
    Console.WriteLine("Started Executing Callback Operation...");    
    var myCallBackOperationDelegate = new CallBackOperation.MyCallBackOperationDelegate(CallBackOperation.MyMenthod);    
    Console.WriteLine("After BeginInvoke Operation");    
    IAsyncResult asyncResult = myCallBackOperationDelegate.BeginInvoke(5,10,  CallBackOperation.MyCallBackOperation, myCallBackOperationDelegate);    
    Console.WriteLine("Still Executing");    
    Console.ReadKey();    
}    

خروجی برنامه

Started Executing Callback Operation...

After BeginInvoke Operation

Still Executing

Result: 499505 

Polling یک اصطلاح معروف به معنی چک کردن دوره ای  برای یک بیمار خاص است. در این روش به طور مدام میپرسد ایا شما هنوز هم اینجا هستید؟  چک میکند که ایا Task وجود دارد یا نه .

اگر بهره برداری از کار تکمیل شده بود سپس  متد EndInvoke صدا زده می شود.

کد زیر ، مثالی در این باره است.

public class Polling    
{    
    public delegate int MyPollingDelegate(int number, int numberOfTimes);    
    public static int MyCalculation(int number, int numberOfTimes)    
    {    
        for (int i = 0; i < numberOfTimes; i++)    
        {    
            number = number + i;    
        }    
  
        return number;    
    }    
  
    public static void ExecutePollingTechnique()    
    {    
        Console.WriteLine("BeginInvoke Operation Started...");    
        var myPollingDelegate = new MyPollingDelegate(MyCalculation);    
        IAsyncResult asyncResult = myPollingDelegate.BeginInvoke(10, 100, null, null);    
        Console.WriteLine("After BeginInvoke Operation...");    
  
        while (!asyncResult.IsCompleted)    
        {    
            Console.WriteLine("Still in progress...");    
            Console.WriteLine("I am working other operation...");    
        }    
  
        Console.WriteLine("Asynchronous Programming");    
        long myPollingResult = myPollingDelegate.EndInvoke(asyncResult);    
        Console.WriteLine("Resutl : {0}", myPollingResult);    
    }    
  
}   

در حال حاضر متد را اجرا میکنیم

static void Main(string[] args)  
{  
     Polling.ExecutePollingTechnique();  
     Console.ReadKey();  
} 

خروجی

BeginInvoke Operation Started...

After BeginInvoke Operation...

Still in progress...

I am working other operation...

Still in progress...

I am working other operation...

Still in progress...

I am working other operation...

Still in progress...

I am working other operation...

Still in progress...

I am working other operation...

Asynchronous Programming...

Result : 4960  

EndInvoke

در واقع  به طور کلی با 2 متد  BeginInvoke و EndInvoke استفاده می شود.

این تکنیک اساسی از threading با استفاده از Delegate است.

کد زیر به عنوان مثال است

public delegate int MyMessageDelegate(int numberOfTimes, int number);  
public  class EndInvoke  
{  
    public static int ShowMessage(int numberOfTimes, int number)  
    {  
        for (int counter = 0; counter <= numberOfTimes; counter++)  
        {  
            number = number + counter;  
        }  
  
        return number;  
    }  
  
}  

متد را اجرا کنید

static void Main(string[] args)    
{    
    var myMessageDelegate = new MyMessageDelegate(EndInvoke.ShowMessage);    
    Console.WriteLine("BeginInvoke Operation Started...");    
    IAsyncResult asyncResult = myMessageDelegate.BeginInvoke(10, 5, null, null);    
    Console.WriteLine("After BeginInvoke Operation....");    
    var myMessageResult = myMessageDelegate.EndInvoke(asyncResult);    
    Console.WriteLine("EndInvoke Operation Finished...");    
    Console.WriteLine("Result {0}", myMessageResult);    
    Console.ReadKey();    
}   

خروجی  را ببینید

BeginInvoke Operation Started...

After BeginInvoke Operation...

EndInvoke Operation Finished..

Result 60 

آموزش سی شارپ  

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان
  • C#.net
  • 2k بازدید
  • 2 تشکر

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید