c#中的异步编程模型

在读文件的时候,如果不采用异步模型,整个执行线程会挂起,直至文件读取完毕,这个时候这个线程就会一直等待直到文件读取完成为止极大的浪费资源;如果是从网络上读取文件的话,如果网络中断那么就只能抛出异常了(而线程只能忙等)。
public IAsyncResult BeginReceive(
 IList<ArraySegment<byte>> buffers,
 SocketFlags socketFlags,
 AsyncCallback callback,
 Object state)
public int EndReceive(
 IAsyncResult asyncResult)
异步模型:必然有第三,第四个参数(两者可以置为null),并返回一个IAsyncResult的类型,异步期间采用硬件驱动监听,而不需要任何线程在这里等待;
异步编程模型的三个技术要点:第四个参数是传递给回调函数的
1.采用:人工调节
BeginReceive();
...
...
EndReceive();
自己采用一个适当的时间,在EndReceive()中返回本应该在同步模型中返回的值,如此处返回int,Accept()返回一个socket,但是这导致根本没有发挥出异步的全部能力。
等待直至完成:在执行到End..函数的时候就会默认静止,从而只能节省一部分时间;
2.间歇查询
public interface IAsyncResult {
 Object AsyncState { get; }
 WaitHandle AsyncWaitHandle { get; }
 Boolean IsCompleted { get; }
 Boolean CompletedSynchronously { get; }  //不需要使用
}
线程询问:
IAsyncResult ar = fs.BeginRead(data, 0, data.Length, null, null);
while (!ar.IsCompleted) {
 Console.WriteLine("Operation not completed; still waiting.");
 Thread.Sleep(10);
}                    //直到可以确定完成了
Int32 bytesRead = fs.EndRead(ar);

类似的有:
while (!ar.AsyncWaitHandle.WaitOne(10, false)) {
Console.WriteLine("Operation not completed; still waiting.");
}
Int32 bytesRead = fs.EndRead(ar);

3.回调函数
delegate void AsyncCallback(IAsyncResult ar); 回调函数的委托(回调函数实现采用相同类型的参数,直接传入函数名)
默认将第四个object参数转换为回调函数的相应的IAsyncResult参数。
object 是一个传递给回调函数的任意类型的参数,但是要用IAsyncResult的AsyncState来显示转换
在回调函数中调用end..函数,彻底完成异步操作。(回调函数可能不是定义在一个类中)
但是在回调函数可能要和异步开始调用的函数中公用一些数据,如,写文件时候的缓冲区。
优化方法:
1.定义一个类包含一些公用的数据,然后在主函数中声明实例,然后将其做为最后一个参数传递给回调函数。(可以防止过多的静态的数据)
2.匿名委托:(解决data共享问题)
fs.BeginRead(data, 0, data.Length,
delegate(IAsyncResult ar)
{
 Int32 bytesRead = fs.EndRead(ar);    注:用什么调用begin..,就一定要用它来调用end...
 fs.Close();
 Console.WriteLine(BitConverter.ToString(data, 0, bytesRead));
},    null);
3.让每一个异步操作采用自己的一对处理函数,来达到效率的最高。


委托的异步操作模型:
internal sealed class SumDelegate : MulticastDelegate {
 public SumDelegate(Object object, IntPtr method);
 public UInt64 Invoke(UInt64 n);
 public IAsyncResult BeginInvoke(UInt64 n, AsyncCallback callback, Object object);
 public UInt64 EndInvoke(IAsyncResult result);}

 

 

 

 

 

 

 

 

 

 

posted @ 2010-03-19 10:09  天地不仁  阅读(2946)  评论(0编辑  收藏  举报