亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

使用異步方式調用同步方法(實例詳解)

2020-01-24 03:06:05
字體:
來源:轉載
供稿:網友

說明:

.NET Compact Framework 中不支持異步委托調用,也就是 BeginInvoke 和 EndInvoke 方法。

BeginInvoke 方法啟動異步調用。該方法與您需要異步執行的方法具有相同的參數,還有另外兩個可選參數。第一個參數是一個 AsyncCallback 委托,該委托引用在異步調用完成時要調用的方法。第二個參數是一個用戶定義的對象,該對象將信息傳入回調方法。BeginInvoke 會立即返回,而不等待異步調用完成。BeginInvoke 返回一個可用于監視異步調用進度的 IAsyncResult。

EndInvoke 方法檢索異步調用的結果。在調用 BeginInvoke 之后隨時可以調用該方法。如果異步調用尚未完成,則 EndInvoke 會一直阻止調用線程,直到異步調用完成。EndInvoke 的參數包括您需要異步執行的方法的 out 和 ref 參數(在 Visual Basic 中為 <Out> ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。

說明:

Visual Studio 2005 中的 IntelliSense 功能顯示 BeginInvoke 和 EndInvoke 的參數。如果您沒有使用 Visual Studio 或類似工具,或您使用的是帶有 Visual Studio 2005 的 C#,請參見 異步編程概述 以獲取為這些方法定義的參數的說明。

本主題中的代碼示例演示了使用 BeginInvoke 和 EndInvoke 進行異步調用的四種常用方法。調用 BeginInvoke 之后,您可以執行下列操作:

進行某些操作,然后調用 EndInvoke 一直阻止到調用完成。

使用 IAsyncResult.AsyncWaitHandle 屬性獲取 WaitHandle,使用其 WaitOne 方法一直阻止執行直到發出 WaitHandle 信號,然后調用 EndInvoke。

輪詢由 BeginInvoke 返回的 IAsyncResult,以確定異步調用何時完成,然后調用 EndInvoke。

將用于回調方法的委托傳遞給 BeginInvoke。異步調用完成后,將在 ThreadPool 線程上執行該方法?;卣{方法調用 EndInvoke。

重要說明:

無論您使用何種方法,都要調用 EndInvoke 來完成異步調用。

定義測試方法和異步委托

下面的代碼示例演示異步調用同一個長時間運行的方法 TestMethod 的各種方式。TestMethod 方法會顯示一條控制臺消息,說明該方法已開始處理,休眠了幾秒鐘,然后結束。TestMethod 有一個 out 參數,該參數用于演示此種參數添加到 BeginInvoke 和 EndInvoke 的簽名中的方式。您可以按同樣的方式處理 ref 參數。

下面的代碼示例演示 TestMethod 的定義和名為 AsyncMethodCaller 的、可用來異步調用 TestMethod 的委托。若要編譯代碼示例,必須包括 TestMethod 的定義和 AsyncMethodCaller 委托。

C#

復制代碼 代碼如下:

using System;
using System.Threading;
namespace AsyncTest
{
    public class AsyncDemo
    {
        //方法一
        public string TestMethod(int callDuration, out int threadId)
        {
            Console.WriteLine("Test method begins.");
            Thread.Sleep(callDuration);
            threadId = Thread.CurrentThread.ManagedThreadId;
            return String.Format("My call time was {0}.", callDuration.ToString());
        }
//方法二
public float Addxy(float x, float y)
        {
            return x * y;
        }
    }
    //定義兩個對應于方法的委托,參數同方法一致,委托的聲明寫在調用類里也是一樣的,不限
    public delegate string AsyncMethodCaller(int callDuration, out int threadId);
    public delegate float AsyncMethodCaller2(float x, float y);
}

使用 EndInvoke 等待異步調用

異步執行方法的最簡單方式是通過調用委托的 BeginInvoke 方法來開始執行方法,在主線程上執行一些操作,然后調用委托的 EndInvoke 方法。EndInvoke 可能會阻止調用線程,因為該方法直到異步調用完成后才返回。這種方式非常適合執行文件或網絡操作。

重要說明:

因為 EndInvoke 可能會阻塞,所以不應從服務于用戶界面的線程調用該方法。

C#

復制代碼 代碼如下:

using System;
using System.Threading;
namespace AsyncTest
{
    public class AsyncMain
    {
        public static void Main()
        {
            // The asynchronous method puts the thread id here.
            int threadId;
            //實例化.
            AsyncDemo ad = new AsyncDemo();
            // 定義委托
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);

            //通過委托調用方法,回調函數為null
            IAsyncResult result = caller.BeginInvoke(3000,
                out threadId, null, null);

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

            // Call EndInvoke to wait for the asynchronous call to complete,會阻塞
            // and to retrieve the results.
            string returnValue = caller.EndInvoke(out threadId, result);

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


使用 WaitHandle 等待異步調用

您可以使用由 BeginInvoke 返回的 IAsyncResult 的 AsyncWaitHandle 屬性來獲取 WaitHandle。異步調用完成時會發出 WaitHandle 信號,而您可以通過調用 WaitOne 方法等待它。

如果您使用 WaitHandle,則在異步調用完成之前或之后,但在通過調用 EndInvoke 檢索結果之前,還可以執行其他處理。

說明:

調用 EndInvoke 時不會自動關閉等待句柄。如果釋放對等待句柄的所有引用,則當垃圾回收功能回收等待句柄時,將釋放系統資源。若要在等待句柄使用完畢后立即釋放系統資源,請調用 WaitHandle.Close 方法來釋放等待句柄。顯式釋放可釋放的對象時,垃圾回收的工作效率會更高。

C#

復制代碼 代碼如下:

using System;
using System.Threading;
namespace AsyncTest
{
    public class AsyncMain
    {
        static void Main()
        {
            // The asynchronous method puts the thread id here.
            int threadId;
            //實例化
            AsyncDemo ad = new AsyncDemo();

            //定義委托.
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);

            //調用
            IAsyncResult result = caller.BeginInvoke(3000,
                out threadId, null, null);

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

            // Wait for the WaitHandle to become signaled.
            result.AsyncWaitHandle.WaitOne();

            // Perform additional processing here.
            // Call EndInvoke to retrieve the results.
            string returnValue = caller.EndInvoke(out threadId, result);

            // Close the wait handle.
            result.AsyncWaitHandle.Close();

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


/*輸出如下:
Main thread 1 does some work.
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
*/

輪詢異步調用完成

您可以使用由 BeginInvoke 返回的 IAsyncResult 的 IsCompleted 屬性來發現異步調用何時完成。從用戶界面的服務線程中進行異步調用時可以執行此操作。輪詢完成允許調用線程在異步調用在 ThreadPool 線程上執行時繼續執行。

C#C++VB

復制代碼 代碼如下:

using System;
using System.Threading;
namespace AsyncTest
{
    public class AsyncMain
    {
        static void Main() {
            // The asynchronous method puts the thread id here.
            int threadId;

            //實例化.
            AsyncDemo ad = new AsyncDemo();

            //聲明委托
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);

            //調用.
            IAsyncResult result = caller.BeginInvoke(3000,
                out threadId, null, null);

            //輪詢.
            while(result.IsCompleted == false) {
                Thread.Sleep(250);
                Console.Write(".");
            }
            //取結果.
            string returnValue = caller.EndInvoke(out threadId, result);

            Console.WriteLine("/nThe call executed on thread {0}, with return value /"{1}/".",
                threadId, returnValue);
        }
    }
}


/* 輸出:
Test method begins.
.............
The call executed on thread 3, with return value "My call time was 3000.".
*/

異步調用完成時執行回調方法

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

若要使用回調方法,必須將表示回調方法的 AsyncCallback 委托傳遞給 BeginInvoke。也可以傳遞包含回調方法要使用的信息的對象。在回調方法中,可以將 IAsyncResult(回調方法的唯一參數)強制轉換為 AsyncResult 對象。然后,可以使用 AsyncResult.AsyncDelegate 屬性獲取已用于啟動調用的委托,以便可以調用 EndInvoke。

有關示例的說明:

TestMethod 的 threadId 參數為 out 參數(在 Visual Basic 中為 <Out> ByRef),因此 TestMethod 從不使用該參數的輸入值。會將一個虛擬變量傳遞給 BeginInvoke 調用。如果 threadId 參數為 ref 參數(在 Visual Basic 中為 ByRef),則該變量必須為類級別字段,這樣才能同時傳遞給 BeginInvoke 和 EndInvoke。

傳遞給 BeginInvoke 的狀態信息是一個格式字符串,回調方法使用該字符串來設置輸出消息的格式。因為作為類型 Object 進行傳遞,所以狀態信息必須強制轉換為正確的類型才能被使用。

回調是在 ThreadPool 線程上進行的。ThreadPool 線程是后臺線程,這些線程不會在主線程結束后保持應用程序的運行,因此示例的主線程必須休眠足夠長的時間以便回調完成。

C#

復制代碼 代碼如下:

using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;
namespace AsyncTest
{
    public class AsyncMain
    {
        static void Main()
        {
            //實例化類.
            AsyncDemo ad = new AsyncDemo();

            //實例兩個不同的委托,分別對應不同的方法.
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);

AsyncMethodCaller2 caller2 = new AsyncMethodCaller2(ad.Addxy);

            // The threadId parameter of TestMethod is an out parameter, so
            // its input value is never used by TestMethod. Therefore, a dummy
            // variable can be passed to the BeginInvoke call. If the threadId
            // parameter were a ref parameter, it would have to be a class-
            // level field so that it could be passed to both BeginInvoke and
            // EndInvoke.
            int dummy = 0;

            // 調用時指定回調方法,在異步執行完后會自動調用該方法,用來取得執行的結果
            IAsyncResult result = caller.BeginInvoke(3000,
                out dummy,
                new AsyncCallback(CallbackMethod),
                "The call executed on thread {0}, with return value /"{1}/".");

caller2.BeginInvoke(2, 3, CallbackMethod2, "this is add");
            Console.WriteLine("The main thread {0} continues to execute...",
                Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(4000);

            Console.WriteLine("The main thread ends.");
        }

        // The callback method must have the same signature as the
        // AsyncCallback delegate.
        private void CallbackMethod(IAsyncResult ar)
        {
            // Retrieve the delegate.
            AsyncResult result = (AsyncResult) ar;
   //強制轉換成對應的委托對象
            AsyncMethodCaller caller = (AsyncMethodCaller) result.AsyncDelegate;

            // Retrieve the format string that was passed as state
            // information.
            string formatString = (string) ar.AsyncState;

            // Define a variable to receive the value of the out parameter.
            // If the parameter were ref rather than out then it would have to
            // be a class-level field so it could also be passed to BeginInvoke.
            int threadId = 0;
            // Call EndInvoke to retrieve the results.
            string returnValue = caller.EndInvoke(out threadId, ar);


            // Use the format string to format the output message.
            Console.WriteLine(formatString, threadId, returnValue);
        }
private void CallbackMethod2(IAsyncResult ar)
        {
            // Retrieve the delegate.
            AsyncResult result = (AsyncResult)ar;
//強制轉換成對應的委托對象
            AsyncMethodCaller2 caller = (AsyncMethodCaller2)result.AsyncDelegate;

            // 取得狀態
            string formatString = (string)ar.AsyncState;
            //調用異步完成的方法,取得執行結果
            string returnValue = caller.EndInvoke(ar).ToString();

//此種方式是在windows應用程序給控件賦值時用,因為在非創建線程不能操作控件
            this.Invoke(new Action<string>((u) => tb_datainfo.Text += u), returnValue);
            //tb_datainfo.Text = caller.EndInvoke(out threadId, ar);

            // Use the format string to format the output message.
            //Console.WriteLine(formatString, threadId, returnValue);
        }
    }
    }
}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日韩爱爱视频| 亚洲一区二区国产| 成人在线播放av| 91精品国产91久久久久福利| 中文字幕国内精品| 久久久久久久久久国产精品| 欧美一区二区三区……| 一色桃子一区二区| 欧美日韩亚洲视频| 国产欧美一区二区三区在线| 欧美自拍视频在线| 日韩美女免费视频| 91精品国产91久久久久久久久| 亚洲国产婷婷香蕉久久久久久| 成人性生交大片免费看小说| 精品国产31久久久久久| 91日本视频在线| 亚洲精品一区二三区不卡| 久久九九有精品国产23| 国产亚洲视频中文字幕视频| 俺去亚洲欧洲欧美日韩| 亚洲高清在线观看| 久热精品视频在线观看一区| 国产999视频| 欧美日韩成人免费| 欧美午夜www高清视频| 亚洲欧美日韩国产中文专区| 国产免费一区二区三区香蕉精| 91免费的视频在线播放| 日韩一级裸体免费视频| 欧美日韩国产999| 欧美激情亚洲激情| 国语自产精品视频在线看| 亚洲精品福利在线| 欧美高清视频在线播放| 亚洲精品美女免费| 欧美日韩性视频在线| 蜜臀久久99精品久久久久久宅男| 欧美成人中文字幕| 91丨九色丨国产在线| 久久久成人精品视频| 亚洲欧美日韩久久久久久| 91精品国产网站| 国内成人精品一区| 精品无人区太爽高潮在线播放| 国内揄拍国内精品少妇国语| 在线观看欧美日韩国产| 精品久久久久久国产91| 日韩av中文字幕在线播放| 欧美色另类天堂2015| 久久成人精品电影| 国产欧美 在线欧美| 国产成人精品在线观看| 日韩欧美精品网址| 97超级碰在线看视频免费在线看| 国产精品青草久久久久福利99| 国产99久久精品一区二区 夜夜躁日日躁| 色老头一区二区三区在线观看| 亚洲色在线视频| 一区二区三区亚洲| 午夜精品一区二区三区在线视频| 日韩av一区二区在线观看| 亚洲国产精久久久久久久| 九九精品在线视频| 国产精品精品久久久| www.亚洲免费视频| 久久久久久久久久国产| 精品中文字幕在线观看| 亚洲精品少妇网址| 亚洲精品久久久久中文字幕欢迎你| 免费不卡欧美自拍视频| 欧美黄网免费在线观看| 久久这里有精品视频| 亚洲偷欧美偷国内偷| 久久久人成影片一区二区三区| 国产精品国产三级国产专播精品人| 亚洲国产精品网站| 尤物tv国产一区| 亚洲理论电影网| 国外视频精品毛片| 91精品免费视频| 亚洲国产精久久久久久| 久久视频在线视频| 亚洲毛茸茸少妇高潮呻吟| 成人免费看吃奶视频网站| 一区二区中文字幕| 亚洲国产一区自拍| 国产精品无av码在线观看| 久久久久久久香蕉网| 久久精品亚洲国产| 成人精品福利视频| 92看片淫黄大片欧美看国产片| 国产精品av在线| 国产国语刺激对白av不卡| 欧美久久精品一级黑人c片| 亚洲福利视频网| 91久久久在线| 国产亚洲精品久久久久动| 中文字幕日韩欧美在线| 亚洲国产精品热久久| 国产一区二区丝袜| 97超视频免费观看| 久久视频中文字幕| 欧美激情视频网| 成人a级免费视频| 国产va免费精品高清在线| 国产丝袜高跟一区| 精品一区二区三区电影| 色青青草原桃花久久综合| 国产精品99久久久久久白浆小说| 日本欧美一级片| 97国产精品久久| 欧美在线视频在线播放完整版免费观看| 国产欧美一区二区白浆黑人| 欧美激情在线播放| 国产精品欧美日韩久久| 午夜精品一区二区三区在线| 成人午夜在线影院| 97在线精品国自产拍中文| 欧美黑人国产人伦爽爽爽| 亚洲国产欧美自拍| 国产精品午夜国产小视频| 欧美精品第一页在线播放| 精品久久久香蕉免费精品视频| 2018国产精品视频| 一区二区三区视频在线| 九九热视频这里只有精品| 91精品国产亚洲| 亚洲国产精品视频在线观看| 国产成人极品视频| 青草热久免费精品视频| 成人春色激情网| 亚洲一区二区三区成人在线视频精品| 国内免费精品永久在线视频| 欧美一级黄色网| 成人福利网站在线观看11| 91精品国产综合久久香蕉的用户体验| 国产精品综合网站| 亚洲第一天堂无码专区| 亚洲成人激情小说| 国产精品揄拍一区二区| 久久福利视频导航| 91综合免费在线| 亚洲人成网站色ww在线| 亚洲色图18p| 91精品久久久久久久久久入口| 91精品国产免费久久久久久| 国产精品视频久久久久| 国产一区二区三区高清在线观看| 亚洲欧美在线第一页| 中文字幕久久久av一区| 欧美激情欧美激情在线五月| 国产精品视频最多的网站| 精品偷拍一区二区三区在线看| 国产精品第一视频| 国模私拍一区二区三区| 国产日韩精品在线观看| 国产精品普通话| 亚洲欧美日韩中文在线| 国产999精品| 日韩久久午夜影院| 国语自产在线不卡| 尤物精品国产第一福利三区| 538国产精品一区二区免费视频|