程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#基礎知識 >> C# 異步和委托學習

C# 異步和委托學習

編輯:C#基礎知識

IAsyncResult是接口:

  IAsyncResult 異步設計模式通過名為 BeginOperationName 和 EndOperationName 的兩個方法來實現原同步方法的異步調用,如 FileStream 類提供了 BeginRead 和 EndRead 方法來從文件異步讀取字節,它們是 Read 方法的異步版本

    Begin 方法包含同步方法簽名中的任何參數,此外還包含另外兩個參數:一個AsyncCallback 委托和一個用戶定義的狀態對象。委托用來調用回調方法,狀態對象是用來向回調方法傳遞狀態信息。該方法返回一個實現 IAsyncResult 接口的對象

    End 方法用於結束異步操作並返回結果,因此包含同步方法簽名中的 ref 和 out 參數,返回值類型也與同步方法相同。該方法還包括一個 IAsyncResult 參數,用於獲取異步操作是否完成的信息,當然在使用時就必須傳入對應的 Begin 方法返回的對象實例

    開始異步操作後如果要阻止應用程序,可以直接調用 End 方法,這會阻止應用程序直到異步操作完成後再繼續執行。也可以使用 IAsyncResult 的 AsyncWaitHandle 屬性,調用其中的WaitOne等方法來阻塞線程。這兩種方法的區別不大,只是前者必須一直等待而後者可以設置等待超時

    如果不阻止應用程序,則可以通過輪循 IAsyncResult 的 IsCompleted 狀態來判斷操作是否完成,或使用 AsyncCallback 委托來結束異步操作。AsyncCallback 委托包含一個 IAsyncResult 的簽名,回調方法內部再調用 End 方法來獲取操作執行結果

//C#異步編程模式IAsyncResult之IAsyncResult 接口
public interface IAsyncResult  

{  
    object AsyncState { get; }  
    WaitHandle AsyncWaitHandle { get; }  
    bool CompletedSynchronously { get; }  
    bool IsCompleted { get; }  
} 

以上是IAsyncResult 接口的屬性。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace ConsoleTest
{
    public delegate int AddHandler(int a, int b);
    public class 加法類
    {
        public static int Add(int a, int b)
        {
            Console.WriteLine("開始計算:" + a + "+" + b);
            Thread.Sleep(3000); //模擬該方法運行三秒
            Console.WriteLine("計算完成!");
            return a + b;
        }
    }

    #region 
    public class 同步調用
    {
        static void Main()
        {
            Console.WriteLine("===== 同步調用 SyncInvokeTest =====");
            AddHandler handler = new AddHandler(加法類.Add);
            int result = handler.Invoke(1, 2);

            Console.WriteLine("繼續做別的事情。。。");

            Console.WriteLine(result);
            Console.ReadKey();
        }
    }
    #endregion
}

 /*運行結果:
         ===== 同步調用 SyncInvokeTest =====
         開始計算:1+2
         計算完成!
         繼續做別的事情。。。
         3      

*/

public delegate int AddHandler(int a, int b);
    public class 加法類
    {
        public static int Add(int a, int b)
        {
            Console.WriteLine("開始計算:" + a + "+" + b);
            Thread.Sleep(3000); //模擬該方法運行三秒
            Console.WriteLine("計算完成!");
            return a + b;
        }
    }

    
    #region 異步調用
    public class 異步調用
    {
        static void Main()
        {
            Console.WriteLine("===== 異步調用 AsyncInvokeTest =====");
            AddHandler handler = new AddHandler(加法類.Add);

            //IAsyncResult: 異步操作接口(interface)
            //BeginInvoke: 委托(delegate)的一個異步方法的開始
            IAsyncResult result = handler.BeginInvoke(1, 2, null, null);

            //如果在2秒內完成計算
            if (result.AsyncWaitHandle.WaitOne(2000, true))
            {
                Console.WriteLine(handler.EndInvoke(result));
                Console.WriteLine(result);
            }

            Console.WriteLine("繼續做別的事情。。。");

            //異步操作返回
            Console.WriteLine(handler.EndInvoke(result));
            Console.ReadKey();
        }

運行結果:

異步回掉:

 public delegate int AddHandler(int a, int b);
    public class 加法類
    {
        public static int Add(int a, int b)
        {
            Console.WriteLine("開始計算:" + a + "+" + b);
            Thread.Sleep(3000); //模擬該方法運行三秒
            Console.WriteLine("計算完成!");
            return a + b;
        }
    }

   
    #region 異步回掉函數
    public class 異步回調
    {
        static void Main()
        {
            Console.WriteLine("===== 異步回調 AsyncInvokeTest =====");
            AddHandler handler = new AddHandler(加法類.Add);

            //異步操作接口(注意BeginInvoke方法的不同!)
            IAsyncResult result = handler.BeginInvoke(1,2,new AsyncCallback(回調函數),"AsycState:OK");
            //IAsyncResult result1 = handler.BeginInvoke(3, 4, new AsyncCallback(CallBackFuncation), "異步回掉完成");

            Console.WriteLine("繼續做別的事情。。。");
            Console.ReadKey();
        }

        static void 回調函數(IAsyncResult result)
        {
            //result 是“加法類.Add()方法”的返回值
            //AsyncResult 是IAsyncResult接口的一個實現類,引用空間:System.Runtime.Remoting.Messaging
            //AsyncDelegate 屬性可以強制轉換為用戶定義的委托的實際類。
            AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;
            Console.WriteLine(handler.EndInvoke(result));
            Console.WriteLine(result.AsyncState);
        }
View Code

使用事件異步計算:

 public class TestFun
 {
        //模擬一個耗時計算
        static int LongTimeMethod()
        {
            int result = 0;
            //Thread. Sleep(3000);
            for (int i = 0; i <= 100; i++)
            {
                result += i;
            }
            return result;
        }

        static void Main()
        {

            //這裡用到的是.Net中定義好的委托來執行BeginInvoke
            Func<int> longTimeAction = new Func<int>(LongTimeMethod);
            IAsyncResult asynResult = longTimeAction.BeginInvoke(null, null);

            //WaitOne
            //這個對象有一個WaitOne方法,還能接受一個超時時間,它會等待這個超時時間指定的長度
            Func<int> longTimeAction1 = new Func<int>(LongTimeMethod);
            IAsyncResult asynResult1 = longTimeAction1.BeginInvoke(null, null);
            //可以繼續處理別的事情
            if (asynResult1.AsyncWaitHandle.WaitOne(10000, true))//判斷是不是結果為true,只等你10s
            {
                int result1 = longTimeAction1.EndInvoke(asynResult1);
                Console.WriteLine(result1);
            }
  }

運行結果:

    public class TestFun
    {
    //模擬一個耗時計算
    static int LongTimeMethod()
    {
        int result = 0;
        //Thread. Sleep(3000);
        for (int i = 0; i <= 100; i++)
        {
            result += i;
        }
        return result;
    }

    static void Main()
    {
        //這裡用到的是.Net中定義好的委托來執行BeginInvoke
        Func<int> longTimeAction = new Func<int>(LongTimeMethod);
        IAsyncResult asynResult = longTimeAction.BeginInvoke(null, null);

        //輪詢
        while (!asynResult.IsCompleted)
        {
            //當不是true時,就執行這裡的代碼
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("計算還未完成,等待中....");
            Console.ForegroundColor = ConsoleColor.Yellow;
            for (int i = 1; i < 100; i++)
            {
                for (int j = i; j < 100; j++)
                {
                    int a = i, b = j;
                    Console.WriteLine("{0}*{1}={2}", a, b, a * b);
                }
            }
            Console.Clear();
        }
        int result1 = longTimeAction.EndInvoke(asynResult);//當是true時,就將結果返回顯示
        Console.WriteLine("計算的結果為:" + result1);
        Console.ReadLine();
    }

運行結果:

完整代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace ConsoleTest
{
    public delegate int AddHandler(int a, int b);
    public class 加法類
    {
        public static int Add(int a, int b)
        {
            Console.WriteLine("開始計算:" + a + "+" + b);
            Thread.Sleep(3000); //模擬該方法運行三秒
            Console.WriteLine("計算完成!");
            return a + b;
        }
    }

    public class TestFun
    {
        //模擬一個耗時計算
        static int LongTimeMethod()
        {
            int result = 0;
            //Thread. Sleep(3000);
            for (int i = 0; i <= 100; i++)
            {
                result += i;
            }
            return result;
        }

        static void Main()
        {

            //這裡用到的是.Net中定義好的委托來執行BeginInvoke
            Func<int> longTimeAction = new Func<int>(LongTimeMethod);
            IAsyncResult asynResult = longTimeAction.BeginInvoke(null, null);

            ////WaitOne
            ////這個對象有一個WaitOne方法,還能接受一個超時時間,它會等待這個超時時間指定的長度
            //Func<int> longTimeAction1 = new Func<int>(LongTimeMethod);
            //IAsyncResult asynResult1 = longTimeAction1.BeginInvoke(null, null);
            ////可以繼續處理別的事情
            //if (asynResult1.AsyncWaitHandle.WaitOne(10000, true))//判斷是不是結果為true,只等你10s
            //{
            //    int result1 = longTimeAction1.EndInvoke(asynResult1);
            //    Console.WriteLine(result1);
            //}

            //回調
            Func<int> longTimeAction2 = new Func<int>(LongTimeMethod);
            //這裡使用了一個lambda表達式,省了不少力啊
            IAsyncResult asynResult2 = longTimeAction.BeginInvoke((result) =>
            {
                int ret = longTimeAction.EndInvoke(result);
                Console.WriteLine(ret);
            }, null);

            //輪詢
            while (!asynResult.IsCompleted)
            {
                //當不是true時,就執行這裡的代碼
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("計算還未完成,等待中....");
                Console.ForegroundColor = ConsoleColor.Yellow;
                for (int i = 1; i < 100; i++)
                {
                    for (int j = i; j < 100; j++)
                    {
                        int a = i, b = j;
                        Console.WriteLine("{0}*{1}={2}", a, b, a * b);
                    }
                }
                Console.Clear();
            }
            int result1 = longTimeAction.EndInvoke(asynResult);//當是true時,就將結果返回顯示
            Console.WriteLine("計算的結果為:" + result1);
            Console.ReadLine();
        }
    }

    #region 直接調用
    //public class 同步調用
    //{
    //    static void Main()
    //    {
    //        Console.WriteLine("===== 同步調用 SyncInvokeTest =====");
    //        AddHandler handler = new AddHandler(加法類.Add);
    //        int result = handler.Invoke(1, 2);

    //        Console.WriteLine("繼續做別的事情。。。");

    //        Console.WriteLine(result);
    //        Console.ReadKey();
    //    }
    //    /*運行結果:
    //     ===== 同步調用 SyncInvokeTest =====
    //     開始計算:1+2
    //     計算完成!
    //     繼續做別的事情。。。
    //     3       */
    //}
    #endregion
    #region 異步調用
    //public class 異步調用
    //{
    //    static void Main()
    //    {
    //        Console.WriteLine("===== 異步調用 AsyncInvokeTest =====");
    //        AddHandler handler = new AddHandler(加法類.Add);

    //        //IAsyncResult: 異步操作接口(interface)
    //        //BeginInvoke: 委托(delegate)的一個異步方法的開始
    //        IAsyncResult result = handler.BeginInvoke(1, 2, null, null);

    //        //如果在2秒內完成計算
    //        if (result.AsyncWaitHandle.WaitOne(2000, true))
    //        {
    //            Console.WriteLine(handler.EndInvoke(result));
    //            Console.WriteLine(result);
    //        }

    //        Console.WriteLine("繼續做別的事情。。。");

    //        //異步操作返回
    //        Console.WriteLine(handler.EndInvoke(result));
    //        Console.ReadKey();
    //    }
    //    /*運行結果:
    //     ===== 異步調用 AsyncInvokeTest =====
    //     繼續做別的事情。。。
    //     開始計算:1+2
    //     計算完成!
    //     3       */
    //}
    //#endregion

    //public class 異步回調
    //{
    //    static void Main()
    //    {
    //        Console.WriteLine("===== 異步回調 AsyncInvokeTest =====");
    //        AddHandler handler = new AddHandler(加法類.Add);

    //        //異步操作接口(注意BeginInvoke方法的不同!)
    //        IAsyncResult result = handler.BeginInvoke(1, 2, new AsyncCallback(回調函數), "AsycState:OK");
    //        //IAsyncResult result1 = handler.BeginInvoke(3, 4, new AsyncCallback(CallBackFuncation), "異步回掉完成");

    //        Console.WriteLine("繼續做別的事情。。。");
    //        Console.ReadKey();
    //    }

    //    static void 回調函數(IAsyncResult result)
    //    {
    //        //result 是“加法類.Add()方法”的返回值
    //        //AsyncResult 是IAsyncResult接口的一個實現類,引用空間:System.Runtime.Remoting.Messaging
    //        //AsyncDelegate 屬性可以強制轉換為用戶定義的委托的實際類。
    //        AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;
    //        Console.WriteLine(handler.EndInvoke(result));
    //        Console.WriteLine(result.AsyncState);
    //    }
    //    /*運行結果:
    //    ===== 異步回調 AsyncInvokeTest =====
    //    開始計算:1+2
    //    繼續做別的事情。。。
    //    計算完成!
    //    3
    //    AsycState:OK
    //             */

    //    static void CallBackFuncation(IAsyncResult result)
    //    {
    //        Console.WriteLine("這裡是回掉函數");
    //        AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;
    //        Console.WriteLine(handler.EndInvoke(result));
    //        Console.WriteLine(result.AsyncState);

    //    }
    //}
    #endregion
}
View Code
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved