91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#線程委托BeginInvoke與EndInvoke怎么使用

發布時間:2022-07-13 10:12:33 來源:億速云 閱讀:188 作者:iii 欄目:開發技術

這篇文章主要講解了“C#線程委托BeginInvoke與EndInvoke怎么使用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C#線程委托BeginInvoke與EndInvoke怎么使用”吧!

我們已經知道 C#當中 存在async/await 、BackGroudWorker類以及TPL(任務并行庫)。當然C#還有一些舊的模式來支持異步編程。

1. BeginInovke和EndInvoke簡單介紹

delegate long MyDel(int first, int second);

class Program
{
    static long Sum(int x, int y)
    {
        Console.WriteLine("------Inside Sum@{0}", DateTime.Now.ToString());
        Thread.Sleep(2000);
        return x + y;
    }

    static void Main(string[] args)
    {
        MyDel del = new MyDel(Sum);

        Console.WriteLine("Before BeginInvoke---@{0}", DateTime.Now.ToString());
        IAsyncResult iar = del.BeginInvoke(3, 5, null, null);
        Console.WriteLine("After BeginInvoke@{0}", DateTime.Now.ToString());

        Console.WriteLine("Doing stuff@{0}", DateTime.Now.ToString());

        long result = del.EndInvoke(iar);
        Console.WriteLine("End Invoke@{0}", DateTime.Now.ToString());

        Console.WriteLine("After EndInvoke:  {0}", result);

        Console.ReadKey();

    }
}

如上代碼,定義了一個委托 MyDel ,并且在調用的時候把Sum方法傳給了它的對象。一般情況下我們調用這個委托對象,它就會調用他調用列表中包含的方法。就想調用方法一樣,這是同步完成的。

但是如果委托對象在調用列表中只有一個方法(引用方法),它就可以異步的去執行這個方法。BeginInovke和EndInvoke就是用來做這個事的。我們可以用如下的方式使用:

  • ①當我們調用BeginInvoke方法的時候,他開始在一個獨立的線程上執行引用方法,并且立即返回到原始線程。原始線程可以繼續,而引用方法會在想吃的線程中并行執行。

  • ②當程序希望獲取已完成的異步方法的結果時,可以檢查BeginInvoke返回的IAsyncResult的IsCompleted屬性,或者調用委托的EndInvoke方法來等待委托執行完成。

上面的使用過程就引出的三種模式:

  • ①等待-直到完成 原始線程在發起了異步方法以及做了一些其他處理之后,原始線程就中斷并且等待異步方法執行完成之后再繼續。

C#線程委托BeginInvoke與EndInvoke怎么使用

  • ②輪詢 ,原始線程定期檢查發起的線程是否完成,如果沒有則可以繼續做其他的事情,

C#線程委托BeginInvoke與EndInvoke怎么使用

  • ③回調 原始線程一直執行,無需等待或者檢查發起的線程是否完成,發起的線程中的引用發放完成之后,發起的線程會調用回調方法,由回調方法在調用的EndInvoke之前處理異步方法的結果。

C#線程委托BeginInvoke與EndInvoke怎么使用

2.BeginInovke和EndInvoke詳細

對于 BeginInvoke 方法,有幾個注意的地方

① 我們可以根據上面的代碼知道,BeginInvoke的參數包含如下兩個部分

  • 引用方法的參數

  • CallBack參數和State參數

②BeginInvoke 會在線程池中找到一個線程,讓引用方法運行在該線程上

③BeginInvoke 返回給調用線程一個實現IAsyncResult接口的對象的引用。這個接口引用包含了在線程池線程中運行的異步方法的狀態。可以判斷這個狀態來確定異步方法是否結束。

// 3和5是引用方法參數,兩個null分別是Callback參數和State參數
// iar是新線程的信息
IAsyncResult iar = del.BeginInvoke(3, 5, null, null);

對于 EndInvoke 方法,有幾個注意的地方

①他的參數是上面BegionInvoke返回的IAsyncResult接口的引用對象,傳入這個對象是便于EndInvoke去找到引用方法運行的線程。并且這個參數置于參數列表最后一個。EndInvoke提供了從異步方法調用的所有輸出,包括ref和out參數。如果委托的引用方法有ref和out參數,他們必須包含在EndInvoke的參數列表當中

IAsyncResult iar2 = del2.BeginInvoke(3, 5, out res, null, null);
del2.EndInvoke(out res, iar2);

②如果線程已經退出了,EndInvoke會做如下事情:

  • 清理退出的線程的狀態并且釋放資源

  • 找到引用方法的返回值,并作為自己的返回值

③如果EndInovke發現線程還在運行中,那么調用線程就會停止并等待,直到清理完畢并返回值。

④因為EndInvoke會去清理線程信息,所以BeginInvoke和EndInvoke必須成對使用。

⑤如果異步方法出現異常,那么在調用EndInvoke的時候會拋出異常。

3.AsyncResult類

上面說BeginInvoke方法返回了一個IAsyncResult接口的引用對象(內部是AsyncResult類的對象),AsyncResult類型表現了異步方法的狀態。下面是這類的主要組成部分:

C#線程委托BeginInvoke與EndInvoke怎么使用

C#線程委托BeginInvoke與EndInvoke怎么使用

4.三種模式

① 等待-直到完成 (比較簡單的模式)

//開始執行異步方法
IAsyncResult iar = del.BeginInvoke(3, 5, null, null);
//Do Something 耗時
del2.EndInvoke(iar);

像上面的代碼,BeginInvoke之后,做了一些事情,然后調用EndInvoke來處理結果,這種方式就是等待-直到完成的模式。

②輪詢模式

輪詢模式中,原始的線程發起了異步的方法調用,做一些事情,然后使用IAsyncResult中的IsComplete熟悉來定期檢查開啟的線程是否完成。如果未完成就在去做一些其他事情。

delegate long MyDel(int first, int second);

class Program
{
    static long Sum(int x, int y)
    {
        Console.WriteLine("--Inside Sum@{0}", DateTime.Now.ToString());
        Thread.Sleep(200);
        return x + y;
    }

    static void Main(string[] args)
    {
        MyDel del = new MyDel(Sum);
        //開始執行異步方法
        IAsyncResult iar = del.BeginInvoke(3, 5, null, null);
        //輪詢開始
        while (!iar.IsCompleted)
        {
            //未完成,執行下面的語句
            for (long i = 0; i < 20000000; i++)
                ;
        }
        //執行完成調用EndInvoke獲取結果
        long result = del.EndInvoke(iar);
        Console.ReadKey();
    }
}

③回調模式

前兩種都是主動方式的,原始線程一直在監控這新開啟的線程。但是回調是被動的,一旦原始線程發起了異步方法,它就自己管自己了,不在考慮同步。

當異步方法調用結束之后,系統調用一個用戶自定義的方法來處理結果,并且調用委托的EndInvoke方法。這個用戶自定義的方法就是回調方法。

上面的BegionInvoke中寫過,他會有兩個參數一個Callback參數和一個State參數.

CallBack參數:是回調方法的名稱。

State參數:可以是null,或者傳入回調方法的一個對象的引用。我們可以用IAsyncResult參數的AsyncState屬性來獲取這個對象,參數的類型是object。

C#線程委托BeginInvoke與EndInvoke怎么使用

a.回調方法:

回調方法的簽名和返回類型必須和 AsyncCallback委托類型所描述的形式一致。

C#線程委托BeginInvoke與EndInvoke怎么使用

兩種方式,構建這個AsyncCallback參數

new AsyncCallback 對象  

IAsyncResult iar = del.BeginInvoke(3, 5, new AsyncCallback(CallWhenDone),null);

直接傳回調方法的名稱

IAsyncResult iar = del.BeginInvoke(3, 5, CallWhenDone, null);

其中 CallWhenDone 如下:

static void CallWhenDone(IAsyncResult iar)
{
    AsyncResult ar = (AsyncResult)iar;
    MyDel del = (MyDel)ar.AsyncDelegate;
    //回調方法中調用了EndInvoke
    long result = del.EndInvoke(iar);
}
b.在回調方法中調用EndInvoke

上面代碼中,在回調中使用了EndInvoke,上文中說到 EndInvoke的調用,是委托的調用,并且需要傳入一個IAsyncResult的接口對象的引用。

所以想要在回調方法里面,調用這個EndInvoke,就得拿到兩個東西一個是委托對象、一個是IAsyncResult,由于我們AsyncCallback委托本身就是必須要傳入IAsyncResult 的,所以這個比較容易,剩下的就是委托對象本身了。在AsyncResult類小節里面我看到,它里面存著一個 AsyncDelegate(它就是委托對象的引用),還有就是 IAsyncResult接口對象在內部就是AsyncResult類對象。所以才可以像上main的代碼,通過強制類型轉換得到MyDel的對象。

C#線程委托BeginInvoke與EndInvoke怎么使用

第二種方法就是如果State參數沒有用處,可以通過State參數,把委托的對象傳過去。

調用的地方,最后一個參數傳入del

IAsyncResult iar = del.BeginInvoke(3, 5, new AsyncCallback(CallWhenDone),del);

回調方法:

static void CallWhenDone(IAsyncResult iar)
{
    MyDel del = (MyDel)iar.AsyncState;
    long result = del.EndInvoke(iar);
}

感謝各位的閱讀,以上就是“C#線程委托BeginInvoke與EndInvoke怎么使用”的內容了,經過本文的學習后,相信大家對C#線程委托BeginInvoke與EndInvoke怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

湄潭县| 湾仔区| 邢台县| 洱源县| 安西县| 齐河县| 江北区| 黎川县| 江华| 巧家县| 灵川县| 台州市| 马山县| 江源县| 马公市| 小金县| 凉城县| 西城区| 江川县| 宽城| 雅安市| 老河口市| 贺州市| 泰州市| 朝阳市| 绥德县| 荣成市| 新昌县| 松桃| 漳浦县| 新沂市| 黔南| 荆门市| 潼关县| 靖江市| 重庆市| 独山县| 治县。| 岐山县| 特克斯县| 绍兴市|