轮询聚集技巧在读取本地文件或做其它操作时,实际上将操作请求加入到Windows设备驱动程序的队列中,而Windows的设备驱动程序知道如何与正确的硬件设备通信,就这样,硬件接管了该操作,也就不需要任何线程来执行任何操作,但是应用程序的线程会等待操作系统完成信息的通知,那么本线程会处在一个While循环里面,直到接收到信息通知后While循环得到满足才会停止循环(上一个文章讲的是等待直至完成聚集技巧,等待直至完成技巧会挂起线程,所以有可能会使主线程挂起,而导致主程序长时间没有响应,而轮询聚集技巧不会出现这种情况,因为他一直都在一个While循环里面,直到Windows有返回信息后,才会执行后面的内容),线程才会继续执行。
在使用APM的轮询聚集技巧例子前,我们先来看一下IAsyncResult接口,这个接口定义了若干只读属性:
public interface IAsyncResult
{
Object AsyncState { get;}
WaitHandle AsyncWaitHandle { get; }
Boolean IsCompleted { get; }
Boolean CompletedSynchronously { get; }
}
目前最常用的属性是AsyncState。
可使用:
IsCompleted 属性
AsyncWaitHandle.WaitOne(10,false) 方法
来询问CLR来查看异步请求是否已经完成运行。
例1:
using System;
using System.IO;
using System.Threading;
namespace program
{
class wangjun
{
static void Main(string[] args)
{
//打开指示异步I/O操作的文件
FileStream fs = new FileStream(@"c:/a.txt",FileMode.Open, FileAccess.Read, FileShare.Read,1024, FileOptions.Asynchronous);
Byte[] data = new byte[100];
//为FileStream对象初始化一个异步读操作
IAsyncResult ar = fs.BeginRead(data, 0, data.Length, null, null);
while (!ar.IsCompleted)
{
Console.WriteLine("Operation not completed; still waiting.");
Thread.Sleep(10);
}
//获取结果。 注意:EndRead方法不能挂起这个线程
Int32 bytesRead = fs.EndRead(ar);
//已经没有操作执行任务了,关闭文件
fs.Close();
//现在中以访问字节数组并显示结果
Console.WriteLine("Number of bytes read={0}", bytesRead);
Console.WriteLine(BitConverter.ToString(data, 0, bytesRead));
}
}
}
例2:
using System;
using System.IO;
using System.Threading;
namespace program
{
class wangjun
{
static void Main(string[] args)
{
//打开指示异步I/O操作的文件
FileStream fs = new FileStream(@"c:/a.txt",FileMode.Open, FileAccess.Read, FileShare.Read,1024, FileOptions.Asynchronous);
Byte[] data = new byte[100];
//为FileStream对象初始化一个异步读操作
IAsyncResult ar = fs.BeginRead(data, 0, data.Length, null, null);
while (!ar.AsyncWaitHandle.WaitOne(10,false))
{
Console.WriteLine("Operation not completed; still waiting.");
Thread.Sleep(10);
}
//获取结果。 注意:EndRead方法不能挂起这个线程
Int32 bytesRead = fs.EndRead(ar);
//已经没有操作执行任务了,关闭文件
fs.Close();
//现在中以访问字节数组并显示结果
Console.WriteLine("Number of bytes read={0}", bytesRead);
Console.WriteLine(BitConverter.ToString(data, 0, bytesRead));
}
}
}