F#与ASP.NET(2):使用F#实现基于事件的异步模式 - 面向对象网 f# 学习 对象 - 面向对象技术开发

面向对象技术开发

会员投稿 投稿指南 站长资讯通告:
您的位置: 首页 > OOP语言 > F# > 正文

F#与ASP.NET(2):使用F#实现基于事件的异步模式

来源: www.bianceng.cn 阅读:

在上一篇文章中,我们的简单讨论了.NET中两种异步模型以及它们在异常处理上的区别,并且简单观察了ASP.NET MVC 2中异步Action的编写方式。从中我们得知,ASP.NET MVC 2的异步Action并非使用了传统基于Begin/End的异步编程模型,而是另一种基于事件的异步模式。此外,ASP.NET MVC 2对于这种异步模式提供了必要的支持,使此方面的程序设计变得相对简单一些。但是,简单的原因主要还是在于已经由其他组件提供了良好的,基于事件的异步模式。那么现在我们就来看看一般我们应该如何来实现这样的功能,以及F#是如何美化我们的生活的吧。

异步数据传输

我们为什么要异步,主要目的之一还是提高I/O操作的伸缩性。I/O操作主要是I/O设备的事情,这些设备在好好工作的时候,是不需要系统花心思进行照看的,它们只要能够在完成指定工作后通知系统就可以了。这也是异步I/O高效的原理,因为它将程序从等待I/O完成的苦闷中解脱出来,这对用户或是系统来说都是一件绝好的事情。

那么说到I/O操作,最典型的场景之一便是数据传输了。比如有两个数据流streamIn和streamOut,我们需要异步地从streamIn中读取数据,并异步地写入到streamOut中。在这个过程中,我们使用一个相对较小的byte数组作为缓存空间,这样程序在进行数据传输时便不会占用太多内存。那么,如果现在需要您编写一个组件完成这样的数据传输工作,并使用标准的基于事件的异步模式释放出来,您会怎么做?

再�嗦一次,基于事件的异步模式,要求在任务完成时使用事件进行提示。同时在出错的时候将异常对象保存在事件的参数中。现在我已经帮您写好了这样的事件参数:

public class CompletedEventArgs : EventArgs
{
   public CompletedEventArgs(Exception ex)
   {
     this.Error = ex;
   }

   public Exception Error { get; private set; }
}

那么接下来的工作就交给您了,加油!

嗯?那么快就写完啦?再想想?如果真确定了,就展开下面的代码对比一下吧:

public class AsyncTransfer
{
   private Stream m_streamIn;
   private Stream m_streamOut;

   public AsyncTransfer(Stream streamIn, Stream streamOut)
   {
     this.m_streamIn = streamIn;
     this.m_streamOut = streamOut;
   }

   public void StartAsync()
   {
     byte[] buffer = new byte[1024];

     this.m_streamIn.BeginRead(
       buffer, 0, buffer.Length,
       this.EndReadInputStreamCallback, buffer);
   }

   private void EndReadInputStreamCallback(IAsyncResult ar)
   {
     var buffer = (byte[])ar.AsyncState;
     int lengthRead;

     try
     {
       lengthRead = this.m_streamIn.EndRead(ar);
     }
     catch (Exception ex)
     {
       this.OnCompleted(ex);
       return;
     }

     if (lengthRead <= 0)
     {
       this.OnCompleted(null);
     }
     else
     {
       try
       {
         this.m_streamOut.BeginWrite(
           buffer, 0, lengthRead,
           this.EndWriteOutputStreamCallback, buffer);
       }
       catch (Exception ex)
       {
         this.OnCompleted(ex);
       }
     }
   }

   private void EndWriteOutputStreamCallback(IAsyncResult ar)
   {
     try
     {
       this.m_streamOut.EndWrite(ar);

       var buffer = (byte[])ar.AsyncState;
       this.m_streamIn.BeginRead(
         buffer, 0, buffer.Length,
         this.EndReadInputStreamCallback, buffer);
     }
     catch (Exception ex)
     {
       this.OnCompleted(ex);
     }
   }

   private void OnCompleted(Exception ex)
   {
     var handler = this.Completed;
     if (handler != null)
     {
       handler(this, new CompletedEventArgs(ex));
     }
   }

   public event EventHandler<CompletedEventArgs> Completed;
}

Tags:
相关文章列表: