zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Python中的unittest和logging
    android短彩信附件机制
    Android Mms之:深入MMS支持
    Android 源码阅读之SMS,MMS
    深度分析:Android4.3下MMS发送到附件为音频文件(音频为系统内置音频)的彩信给自己,添加音频-发送彩信-接收彩信-下载音频附件-预览-播放(一,添加附件)
    使用adb命令对手机进行截屏保存到电脑,SDCard
    Android中检测字符编码(GB2312,ASCII,UTF8,UNICODE,TOTAL——ENCODINGS)方法(二)
    解决新建短信时,输入“+86”,然后输入联系人名字“1”,按删除键之后,联系人变为“1”,删除操作为达到预期结果
    解决:People下面选择分享可见联系人,选择多个联系人后通过短信分享,短信中只显示一个联系人
    解决:短信添加录音附件,录音,没有录音时间限制,超出彩信最大限制也正常录音
  • 原文地址:https://www.cnblogs.com/wuzhang/p/wuzhang20160313.html
Copyright © 2011-2022 走看看