日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

委托之异步

發布時間:2023/12/2 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 委托之异步 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在 使用BackgroundWorker組件 一文中,闡述了在Winform編程中,使用BackgroundWorker組件實現異步調用,本文主要講述利用委托實現異步。

以下描述摘抄于MSDN:

異步委托提供以異步方式調用同步方法的能力。

當同步調用委托時,Invoke()方法直接對當前線程調用目標方法;

當異步調用委托時,CLR將對請求進行排隊并立即返回到調用方,將對來自線程池的線程調用該目標方法,提交請求的原始線程繼續與目標方法并行執行,該目標方法是對線程池線程運行的.

1)、BeginInvoke()方法

BeginInvoke()方法啟動異步調用,它與需要異步執行的方法具有相同的參數。

另外,還有兩個可選參數:第一個參數是AsyncCallback委托,該委托引用在異步調用完成時要調用的方法;第二個參數是用戶定義的對象,該對象可向回調方法傳遞信息;

BeginInvoke立即返回,不等待異步調用完成;

BeginInvoke返回IAsyncResult,這個結果可用于監視異步調用的進度;

2)、EndInvoke()方法

EndInvoke()方法檢索異步調用的結果;

在調用BeginInvoke()方法后,可以隨時調用EndInvoke()方法,如果異步調用尚未完成,則EndInvoke()方法將一直阻止調用線程,直到異步調用完成后才允許調用線程執行;

EndInvoke()的參數需要異步執行的方法的out和ref參數以及由BeginInvoke()返回的IAsyncResult。

?

下面通過代碼闡述異步委托:

代碼一,同步執行:
public delegate int MathDelegate(int x);
public class MathClass
{
public int Add(int x)
{
Thread.Sleep(10000);//此處模擬長時間執行的任務
return x + x;
}
}

public class Program
{
public static void Main(string[] args)
{
MathClass addClass = new MathClass();
MathDelegate mathDel = new MathDelegate(addClass.Add);

//同步執行
int syncResult = mathDel(8);
Console.WriteLine("Sync Proccessing operation...");//這一行只有SyncMethod完成以后才能顯示
Console.WriteLine("Sync Result is: {0}", syncResult);

Console.ReadLine();
}
}
當程序執行到 int syncResult = mathDel(8); 的時候,主線程將等待至少10秒的時間(Add方法的執行),才能執行后面的代碼,也即在期間,應用程序沒有響應,不能執行其他的任何操作,直到Add方法返回結果。
代碼二,異步執行:

我們稍微修改一下Main的代碼:

public static void Main(string[] args)
{
MathClass addClass = new MathClass();
MathDelegate mathDel = new MathDelegate(addClass.Add);

IAsyncResult async = mathDel.BeginInvoke(9, null, null);//在另外的線程里,調用Add方法
Console.WriteLine("Async Proccessing operation...");//立即打印到終端設備
int asyncReuslt = mathDel.EndInvoke(async);
Console.WriteLine("Result is: {0}", asyncReuslt);

Console.ReadLine();
}

在這段代碼中,在開始并沒有直接調用方法,而是使用BeginInvoke()方法,返回IAsyncResult 對象。

代碼三,IsCompleted,輪詢異步調用完成
使用IAsyncResult實例的IsCompleted屬性,以獲取異步操作是否已完成的指示,如果操作完成則為True,否則為False。

修改一下Main的代碼:

public static void Main(string[] args)
{
MathClass addClass = new MathClass();
MathDelegate mathDel = new MathDelegate(addClass.Add);

IAsyncResult async = mathDel.BeginInvoke(9, null, null);//在另外的線程里,調用Add方法
Console.WriteLine("Async Proccessing operation...");//立即打印到終端設備

int i = 1;
while (async.IsCompleted==false)
{
Thread.Sleep(i * 1000);
Console.WriteLine("IsCompleted:{0},{1}", async.IsCompleted, i);
i++;
}
int asyncReuslt = mathDel.EndInvoke(async);
Console.WriteLine("Result is: {0}", asyncReuslt);

Console.ReadLine();
}
代碼四,AsyncCallback,異步調用完成時執行回調方法

如果啟動異步調用的線程不需要是處理結果的線程,則可以在調用完成時執行回調方法;

如果要使用回調方法,必須將引用回調方法AsyncCallback委托傳遞給BeginInvoke()方法,也可以傳遞包含回調方法將要使用的信息的對象。

修改一下Main的代碼:

public static void Main(string[] args)
{
MathClass addClass = new MathClass();
MathDelegate mathDel = new MathDelegate(addClass.Add);

IAsyncResult async = mathDel.BeginInvoke(9, new AsyncCallback(CompleteMethod), "信息來自于主線程");//在另外的線程里,調用Add方法
Console.WriteLine("Async Proccessing operation...");//立即打印到終端設備
Console.ReadLine();
}
private static void CompleteMethod(IAsyncResult async)
{
AsyncResult ar = (AsyncResult)async;

MathDelegate del = (MathDelegate)ar.AsyncDelegate;
int result = del.EndInvoke(async);

string mainTheadMsg = ar.AsyncState as string;
Console.WriteLine("{0}, Result is: {1}", mainTheadMsg, result);
}Add方法調用完成以后,調用 CompleteMethod 方法
結束

轉載于:https://www.cnblogs.com/inforasc/archive/2009/10/21/1587756.html

總結

以上是生活随笔為你收集整理的委托之异步的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。