• .NET的异步调用和IAsyncResult接口


    1.关于委托的BeginInvokeEndInvoke方法

    .NET Framework 允许您异步调用任何方法。为此,应定义与您要调用的方法具有相同签名的委托;公共语言运行库会自动使用适当的签名为该委托定义 BeginInvoke EndInvoke 方法。

    例如:

    namespace carydemo2

    {

        public class CaryAsync

        {       

            public string LongtimeOperation(int data, out int threadId)

            {

                Console.WriteLine("Long time operation begin");

                data = data + 123;

                Thread.Sleep(500);

                threadId = Thread.CurrentThread.ManagedThreadId;

                return String.Format("Data:{0}.", data.ToString());

            }

        }

       

        public delegate string CaryAsyncCaller(int data, out int threadId);

        public class CaryTest

        {

            private static int threadId;

            public static void Main()

            {           

                CaryAsync ca = new CaryAsync();

                CaryAsyncCaller caller = new CaryAsyncCaller(ca.LongtimeOperation);

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

                Thread.Sleep(0);

                Console.WriteLine("Main thread :{0}", Thread.CurrentThread.ManagedThreadId);

                result.AsyncWaitHandle.WaitOne();

                while (result.IsCompleted == false)

                {

                    Thread.Sleep(10);

                }

                string returnValue = caller.EndInvoke(out threadId, result);

                Console.WriteLine("The caller thread: {0}, Data :\"{1}\".", threadId, returnValue);

            }     

        }

    }

    调用你可以使用 BeginInvoke 返回的 IAsyncResult AsyncWaitHandle 属性来获取 WaitHandle。异步调用完成时会发出 WaitHandle 信号,而您可以通过调用 WaitOne 方法等待它。这样你就可以在异步调用完成之前或之后,在通过调用 EndInvoke 检索结果之前,还可以执行其他处理。 

    可以使用由 BeginInvoke 返回的 IAsyncResult IsCompleted 属性来发现异步调用何时完成。 

    还可以在调用完成时执行回调方法,代码如下:

        public class CaryTest

        {

            private static int threadId;

            public static void Main()

            {           

                CaryAsync ca = new CaryAsync();

                CaryAsyncCaller caller = new CaryAsyncCaller(ca.LongtimeOperation);

                IAsyncResult result = caller.BeginInvoke(3000, out threadId, new AsyncCallback(CaryCallBack), caller);

                Console.ReadLine();

     

            }

     

            static void CaryCallBack(IAsyncResult ar)

            {

                CaryAsyncCaller caller = (CaryAsyncCaller)ar.AsyncState;

                string returnValue = caller.EndInvoke(out threadId, ar);

                Console.WriteLine("The caller thread:{0},return value\"{1}\"", threadId, returnValue);

            }

        }

     

    2.IAsyncResult接口:它表示异步操作的状态.该接口定义了4个公用属性,如下:

       AsyncState  获取用户定义的对象,它限定或包含关于异步操作的信息。

       AsyncWaitHandle  获取用于等待异步操作完成的 WaitHandle

       CompletedSynchronously  获取异步操作是否同步完成的指示。

       IsCompleted  获取异步操作是否已完成的指示。 

     

    IAsyncResult 接口由包含可异步操作的方法的类实现。它是启动异步操作的方法的返回类型,如 FileStream.BeginRead,也是结束异步操作的方法的第三个参数的类型,如 FileStream.EndRead。当异步操作完成时,IAsyncResult 对象也将传递给由 AsyncCallback 委托调用的方法。 

    支持 IAsyncResult 接口的对象存储异步操作的状态信息,并提供同步对象以允许线程在操作完成时终止。 

    3. AsyncCallback 委托      

    引用在异步操作完成时调用的回调方法。AsyncCallback 引用的事件处理程序包含完成客户端异步任务的程序逻辑。AsyncCallback 使用 IAsyncResult 接口获取异步操作的状态。

    下面为例子:

    namespace carydemo1

    {

        public class AsyncResult : System.IAsyncResult

        {

            public object AsyncState

            {

                get; set;

            }

            System.Threading.WaitHandle asyncWaitHandle = new AutoResetEvent(false);

            public System.Threading.WaitHandle AsyncWaitHandle

            {

                get { return asyncWaitHandle; }

            }

            public bool CompletedSynchronously

            {

                get; set;

            }

            public bool IsCompleted

            {

                get;

                set;

            }

     

            public int Data

            {

                set;get;

            }

        }

     

        class TestClass

        {

            AsyncCallback asyncCallback;

            AsyncResult asyncResult;

            public TestClass()

            {

                asyncCallback = new AsyncCallback(callback);

                asyncResult = new AsyncResult();

            }

            void callback(IAsyncResult asyncResult)

            {

                AsyncResult temp = asyncResult as AsyncResult;

                ((AutoResetEvent)temp.AsyncWaitHandle).Set();

            }

            public AsyncResult AsyncMethod(int value, object asyncState)

            {

                Console.WriteLine("Start...");

                this.asyncResult.AsyncState = asyncState;

                this.asyncResult.Data = value;

                Thread t = new Thread(new ThreadStart(myThread));

                t.Start();

                return this.asyncResult;

            }

            void myThread()

            {

                Console.WriteLine("begin ");

                for (int i = 0; i < 3; i++)

                {

                    Console.WriteLine(i);

                    asyncResult.Data = asyncResult.Data + i;

                    Thread.Sleep(500);

                }

                Console.WriteLine("end...");

                asyncCallback(this.asyncResult);

            }

        }

     

        class Program

        {

            static void Main(string[] args)

            {

                TestClass obj = new TestClass();

                AsyncResult r = obj.AsyncMethod(50, null);

                r.AsyncWaitHandle.WaitOne();

                System.Console.WriteLine(r.Data);

                System.Console.WriteLine("完成");

                System.Console.Read();

            }

        }

    }

     

     

  • 相关阅读:
    Element库的Vue版本ElementUI的本地引入方法
    在Win7操作系统上安装VS2017报错:安装程序清单签名验证失败
    [转]五大主流浏览器及四大内核
    [转]idea2021.1破解版 附安装教程免激活码
    [转]Node.js安装详细步骤教程(Windows版)
    [转]Windows系统下彻底删除Windows.old 文件夹的方法
    Springboot+Vue进行Web开发时特别需要注意的小事项
    基带信号与频带信号,基带传输与频带传输各是什么?两者有什么区别?
    springboot的Web项目编译运行时提示错误:Field userService in com.cetc.UserManger.controller.UserController required a bean of type 'com.cetc.UserManger.service.UserService' that could not be found.
    创建springboot项目时出现Selected Java version 11 is not supported by SDK (maximum 8)
  • 原文地址:https://www.cnblogs.com/carysun/p/AsyncInvoke.html
Copyright © 2020-2023  润新知