国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
C#異步編程概述
C#異步編程概述

Windows應(yīng)用程序編程中常見的一個(gè)模式就是,在GUI用戶界面下,將耗時(shí)的文件和網(wǎng)絡(luò)處理放入子線程,以避免用戶界面不能響應(yīng)的問題。在.NET出現(xiàn)以前,創(chuàng)建線程并監(jiān)視線程結(jié)束,還要更新界面等工作,即復(fù)雜又要手寫大量代碼,并且難以調(diào)試。在.NET中,程序員可以通過異步調(diào)用,使用簡(jiǎn)單的代碼完成這項(xiàng)工作。

.NET Framework允許異步調(diào)用任何方法。使用異步調(diào)用之前,要定義一個(gè)委托,它的方法簽名要與調(diào)用方法簽名一致。.NET會(huì)自動(dòng)產(chǎn)生此委托的BeginInvoke和EndInvoke方法。

BeginInvoke方法用于啟動(dòng)異步調(diào)用。它除了具有調(diào)用方法相同的參數(shù)外,還附加了兩個(gè)額外的參數(shù),這兩個(gè)額外參數(shù)將用于回調(diào)方法。 BeginInvoke執(zhí)行后立即返回,并不等待異步調(diào)用完成。 BeginInvoke返回一個(gè)IAsyncResult接口,它可以用于監(jiān)視調(diào)用的進(jìn)度。EndInvoke方法被用來獲取異步調(diào)用的結(jié)果。在BeginInvoke執(zhí)行以后,任何時(shí)間都可以調(diào)用EndInvoke。如果異步調(diào)用尚未完成,EndInvoke會(huì)被阻塞,直到異步調(diào)用完成。EndInvoke帶有一個(gè)IAsyncResult接口類型的參數(shù),并返回一個(gè)IAsyncResult接口,用來獲取調(diào)用結(jié)果。

本文中的代碼演示了使用BeginInvoke和EndInvoke進(jìn)行異步調(diào)用的四種常見調(diào)用方式。在調(diào)用BeginInvoke之后,您可以:

    1.完成一些其它工作,然后調(diào)用EndInvoke,等待異步調(diào)用完成。
    2.使用IAsyncResult.AsyncWaitHandle獲取一個(gè)WaitHandle,使用它的WaitOne方法執(zhí)行阻塞調(diào)用,完成后再調(diào)用EndInvoke。
    3.輪詢BeginInvoke返回的IAsyncResult接口,在異步調(diào)用完成后,再調(diào)用EndInvoke。
    4.給BeginInvoke傳遞一個(gè)回調(diào)方法的委托,異步調(diào)用完成后,這個(gè)回調(diào)方法會(huì)在ThreadPool線程上執(zhí)行,可以在這個(gè)方法內(nèi)調(diào)用EndInvoke。

警告:異步調(diào)用完成后,必須調(diào)用EndInvoke。

測(cè)試方法和異步委托

在以下代碼中,都使用同一個(gè)耗時(shí)的測(cè)試方法TestMethod。此方法向控制臺(tái)輸出信息,顯示其開始執(zhí)行,睡眠幾秒鐘,結(jié)束執(zhí)行。TestMethod包含一個(gè)out參數(shù),BeginInvoke和EndInvoke會(huì)同樣包括它,你將來可以自己添加ref參數(shù)。


以下為TestMethod方法和它的委托。

    注意:為了便于說明,TestMethod被定義與與main()不同的一個(gè)類當(dāng)中。當(dāng)然,TestMethod也可以定義為一個(gè)與Main()方法同一個(gè)類當(dāng)中的靜態(tài)方法。


using System;
using System.Threading;

public class AsyncDemo {
    // 異步調(diào)用方法
    public string TestMethod(int callDuration, out int threadId) {
        Console.WriteLine("Test method begins.");
        Thread.Sleep(callDuration);
        threadId = AppDomain.GetCurrentThreadId();
        return "MyCallTime was " + callDuration.ToString();
    }
}

// 委托和調(diào)用方法有相同的簽名
public delegate string AsyncDelegate(int callDuration, out int threadId);

眾代表的字符串AsyncDelegate(整數(shù)callDuration,OUT INT的ThreadID);

調(diào)用EndInvoke,等待異步調(diào)用結(jié)束

異步調(diào)用最簡(jiǎn)單的方法是從BeginInvoke開始,在主線程中完成一些其它工作,然后調(diào)用EndInvoke,直到異步調(diào)用結(jié)束。對(duì)于文件和網(wǎng)絡(luò)操作,這個(gè)技術(shù)不錯(cuò)。但是,由于主線程被阻塞于EndInvoke,該技術(shù)不適于有用戶界面的應(yīng)用程序。

public class AsyncMain {
    static void Main(string[] args) {
        // 異步調(diào)用使用的線程id
        int threadId;

        // 產(chǎn)生類實(shí)例
        AsyncDemo ad = new AsyncDemo();

        // 產(chǎn)生委托
        AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
   
        // 開始異步調(diào)用
        IAsyncResult ar = dlgt.BeginInvoke(3000,
            out threadId, null, null);

        Thread.Sleep(0);
        Console.WriteLine("Main thread {0} does some work.",
            AppDomain.GetCurrentThreadId());

        // 調(diào)用EndInvoke,阻塞并等待完成
        string ret = dlgt.EndInvoke(out threadId, ar);

        Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
    }
}

使用WaitHandle等待異步調(diào)用結(jié)束

等待WaitHandle是一種常見的線程同步技術(shù)。BeginInvoke返回的IAsyncResult接口中,有一個(gè)AsyncWaitHandle屬性。通過調(diào)用它的WaitOne方法,等待異步調(diào)用結(jié)束。一旦異步調(diào)用結(jié)束,還可以有機(jī)會(huì)完成其它工作,最終調(diào)用EndInvoke并獲得異步調(diào)用結(jié)果。

public class AsyncMain {
    static void Main(string[] args) {
        // 異步調(diào)用使用的線程id
        int threadId;

        // 產(chǎn)生類實(shí)例
        AsyncDemo ad = new AsyncDemo();

        // 產(chǎn)生委托
        AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
   
        // 開始異步調(diào)用
        IAsyncResult ar = dlgt.BeginInvoke(3000,
            out threadId, null, null);

        Thread.Sleep(0);
        Console.WriteLine("Main thread {0} does some work.",
            AppDomain.GetCurrentThreadId());

        // 等待WaitHandle得到信號(hào)
        ar.AsyncWaitHandle.WaitOne();

        // 可以完成一些其它工作
        // 最后一定要調(diào)用EndInvoke
        string ret = dlgt.EndInvoke(out threadId, ar);

        Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
    }
}

輪詢異步調(diào)用何時(shí)完成

可以使用由BeginInvoke返回的IAsyncResult接口的IsCompleted屬性判斷調(diào)用是否結(jié)束。用戶界面線程可以輪詢異步調(diào)用狀態(tài),同時(shí)又服務(wù)于用戶輸入。
 
public class AsyncMain {
    static void Main(string[] args) {
        // 異步調(diào)用使用的線程id
        int threadId;

        // 產(chǎn)生類實(shí)例
        AsyncDemo ad = new AsyncDemo();

        // 產(chǎn)生委托
        AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
   
        // 開始異步調(diào)用
        IAsyncResult ar = dlgt.BeginInvoke(3000,
            out threadId, null, null);
            
      // 輪詢
        while(ar.IsCompleted == false) {
            Thread.Sleep(10);
        }

          // 最后一定要調(diào)用EndInvoke
        string ret = dlgt.EndInvoke(out threadId, ar);

        Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
    }
}

在異步調(diào)用完成時(shí)執(zhí)行回調(diào)方法

如果啟動(dòng)異步調(diào)用的線程不需要異步調(diào)用返回的結(jié)果,可以在異步調(diào)用結(jié)束時(shí)在ThreadPool線程上執(zhí)行一個(gè)回調(diào)方法。通過AsyncCallback類型委托,將這個(gè)回調(diào)方法傳遞BeginInvoke。這個(gè)回調(diào)方法可以帶有一個(gè)對(duì)象,供它被調(diào)用時(shí)使用。例如,可以將啟動(dòng)異步調(diào)用的委托傳遞給回調(diào)方法,在回調(diào)方法被調(diào)用時(shí),執(zhí)行EndInvoke。

public class AsyncMain {
    // Asynchronous method puts the thread id here.
    private static int threadId;

    static void Main(string[] args) {
        // 異步調(diào)用使用的線程id
        int threadId;

        // 產(chǎn)生類實(shí)例
        AsyncDemo ad = new AsyncDemo();

        // 產(chǎn)生委托
        AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
   
        // 啟動(dòng)異步調(diào)用,包含一個(gè)AsyncCallback類型的委托,即回調(diào)方法,和回調(diào)方法使用的參數(shù),即啟動(dòng)異步調(diào)用的委托。
        IAsyncResult ar = dlgt.BeginInvoke(3000,
            out threadId,
            new AsyncCallback(CallbackMethod),
            dlgt );

        Console.WriteLine("Press Enter to close application.");
        Console.ReadLine();
    }
    
    // Callback method must have the same signature as the
    // AsyncCallback delegate.
    static void CallbackMethod(IAsyncResult ar) {
        // Retrieve the delegate.
        AsyncDelegate dlgt = (AsyncDelegate) ar.AsyncState;

        // Call EndInvoke to retrieve the results.
        string ret = dlgt.EndInvoke(out threadId, ar);

        Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
    }
}

此文源自MSDN:Asynchronous Programming Overview(http://msdn.microsoft.com/en-us/library/2e08f6yc%28v=vs.71%29.aspx)
譯者:
孫鋼

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C#異步調(diào)用四大方法詳解
MSDN-異步編程概述 [C#] - bitman的專欄 - 博客園
C#異步調(diào)用(Asynchronou Delegate)
C#異步調(diào)用的好處和方法
C#異步調(diào)用的應(yīng)用淺析
C#線程系列講座(1):BeginInvoke和EndInvoke方法
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服