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
原文地址:https://www.cnblogs.com/wuzhang/p/wuzhang20160313.html