In the previous article, we had a brief discussion. NET two asynchronous models and their differences in exception handling, and simply observe how the asynchronous action in ASP.net MVC 2 is written. From this we learned that the asynchronous action of ASP.net MVC 2 did not use the traditional begin/end asynchronous programming model, but another event-based asynchronous Pattern. In addition, ASP.net MVC 2 provides the necessary support for this asynchronous pattern, making this aspect of programming relatively simple. However, the simple reason is that the other components already provide a good, event-based asynchronous Pattern. So let's take a look at how we normally do this and how F # can beautify our lives.
Asynchronous data transfer
One of the main goals of why we want to be asynchronous is to improve the scalability of I/O operations. I/O operations are primarily I/O devices, and these devices do not need to be cared for by the system when they are working well, as long as they are able to notify the system when they are done with the specified work. This is also an efficient principle of asynchronous I/O, because it frees the program from the anguish of waiting for I/O, which is a great thing for the user or the system.
So when it comes to I/O operations, one of the most typical scenarios is data transfer. For example, there are two data streams streamin and streamout, and we need to asynchronously read the data from the StreamIn and write it asynchronously to the streamout. In this process, we use a relatively small byte array as cache space, so that the program does not consume too much memory when it transmits data. So what would you do if you now need to write a component to do the data transfer work and release it using the standard event-based asynchronous Pattern?
Again, the event-based asynchronous Pattern requires that the event be prompted when the task completes. At the same time, the exception object is saved in the parameter of the event when the error occurs. Now I've written the event parameters for you:
public class CompletedEventArgs : EventArgs
{
public CompletedEventArgs(Exception ex)
{
this.Error = ex;
}
public Exception Error { get; private set; }
}
Then the next work will be given to you, come on!
Well? So soon it's finished? Think about it again? If you're sure, expand the following code to compare:
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;
}