使用 IAsyncResult 调用异步方法

现在正在进行异步调用的学习,写篇学习日志,以便加深印象。

在很多时候例如UI或者IO操作时,我们希望将这些很复杂且耗时比较长的逻辑交给后台线程去处理,而不想影响页面的正常运行,基于这种需求越来越多,异步就派上用场了。

异步操作通常用于执行完成时间可能较长的任务,如打开大文件、连接远程计算机或查询数据库等;异步操作在主应用程序线程以外的线程中执行。当应用程序调用方法异步执行某个操作时,应用程序可在异步方法执行其任务时继续执行。

.NET Framework 为异步操作提供两种设计模式:

  • 使用 IAsyncResult 对象的异步操作。

  • 使用事件的异步操作。

之后讲 IAsyncResult方式的实现,在调用使用 IAsyncResult 设计模式的异步方法时可以采用以下几种不同方式:

  •  通过结束异步操作来阻止应用程序执行。
  •  使用 AsyncWaitHandle 阻止应用程序的执行。
  • 轮询异步操作的状态。
  • 使用 AsyncCallback 委托结束异步操作。

上面四种方式可以分为两种情况处理:

A.如果应用程序在等待异步操作结果时不能继续执行其他工作,则在操作完成之前,必须阻止执行其他工作。

可以使用下列方法之一来在等待异步操作完成时阻止应用程序的主线程。

  • 使用异步操作的 BeginOperationName 方法返回的 IAsyncResult 的 AsyncWaitHandle 属性。

  • 调用异步操作的 EndOperationName 方法。

那些在异步操作完成前一直使用一个或多个 WaitHandle 对象阻止其他操作的应用程序通常会调用 BeginOperationName 方法,执行不需要等待操作结果的工作,然后一直等到异步操作完成才停止阻止。通过使用 AsyncWaitHandle 调用 WaitOne 方法,应用程序可以阻止一个操作。若要在等待一组异步操作完成期间阻止执行,应将相关的 AsyncWaitHandle 对象存储在数组中,然后调用 WaitAll 方法。若要在等待一组异步操作中的任一操作完成时阻止其他操作,应将关联的 AsyncWaitHandle 对象存储在数组中,然后调用 WaitAny 方法。

对于调用异步操作的 BeginOperationName 方法,在其后调用对应异步操作的 EndOperationName 方法,就达到阻止主线程操作的效果。

 

B.在等待异步操作结果的同时,可以进行其他工作的应用程序不应在操作完成之前阻止等待。可以使用下列方法之一来在等待异步操作完成的同时继续执行指令。

  • 可使用 AsyncCallback 委托来处理另一个线程中的异步操作的结果。

  • 可使用异步操作的 BeginOperationName 方法返回的 IAsyncResult 的 IsCompleted 属性来确定此操作是否已完成。

之后看下一个借鉴的例子(我也是借鉴的,O(∩_∩)O~~),用回调函数实现的异步方法

        /// <summary>
        /// create file 
        /// </summary>
        /// <param name="config"></param>
        public void Create(IFileConfig1 config)
        {
            var createFileConfig =config  as CreateFileConfig1;
            if (config == null) return;
            //string str = "hello world";
            char [] str = "hello world".ToCharArray();
            byte[] fileStr = Encoding.Default.GetBytes(str);
            FileStream stream = createFileConfig.IsAsync ? new FileStream(createFileConfig.CreateUrl, FileMode.Create,FileAccess.ReadWrite, FileShare.None, 6544, true)
                : new FileStream(createFileConfig.CreateUrl, FileMode.Create);
            using (stream)
            {
                if (!stream.IsAsync && stream.CanWrite)
                    stream.Write(fileStr, 0, fileStr.Length);
                else
                    stream.BeginWrite(fileStr, 0, fileStr.Length, this.End_CreateFileCallBack, stream);
                stream.Close();
               
            }
        }
        /// <summary>
        /// End_CreateFileCallBack
        /// </summary>
        /// <param name="result"></param>
        private void End_CreateFileCallBack(IAsyncResult result)
        {
            var fileStream = result.AsyncState as FileStream;
            Console.WriteLine("异步创建文件地址:{0}",fileStream.Name );
            fileStream.EndWrite(result);
            Console.ReadLine();
        }

刚开始学习,欢迎大家积极的指教!!!

posted @ 2012-12-13 20:26  Susie_hua  阅读(217)  评论(0编辑  收藏  举报