【IT168技术文档】
让我们来看看如何使用异步方式和FileStream类型交互,以此结束对System.IO命名空间的研究。在研究多线程(见第14章)的时候,我们已经看过了.NET Framework提供的异步操作。因为I/O操作可能会花费很多时间,所有从System.IO.Stream派生的类型都有一组方法来实现数据异步操作。我们知道,这需要结合使用IAsyncResult类型:
派生自Stream的类型和异步委托、异步远程方法调用,在异步处理的工作原理上是一致的。然而,让异步行为大大提高文件访问速度是不太可能的,其他的流(比如:基于套接字的流)更有可能从异步处理上得到好处。接下来的例子将说明一种使用FileStream类型进行异步交互的方式。public abstract class System.IO.Stream : MarshalByRefObject, IDisposable { ... public virtual IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state); public virtual IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state); public virtual int EndRead(IAsyncResult asyncResult); public virtual void EndWrite(IAsyncResult asyncResult); }
如果读者能回想起委托的运行过程,那么这个例子(对读者来说)的唯一兴趣点是为了让 FileStream 类型支持异步处理,必须使用一个(这里所显示的)特殊的构造函数。最后一个System.Boolean类型的参数(当它的值设置为true时)告诉FileStream对象在次线程上执行I/O的处理。class Program { static void Main(string[] args) { Console.WriteLine("Main thread started. ThreadID = {0}", Thread.CurrentThread.GetHashCode()); // 必须使用这个构造方法来得到一个支持异步读、写的 FileStream。 FileStream fs = new FileStream("logfile.txt", FileMode.Append, FileAccess.Write, FileShare.None, 4096, true); string msg = "this is atest"; byte[] buffer = Encoding.ASCII.GetBytes(msg); // 开始异步写操作,WriteDone方法在其完成后被调用。 // 注意FileStream 对象作为一个状态信息被传递到回调方法中。 fs.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(WriteDone), fs); } private static void WriteDone(IAsyncResult ar) { Console.WriteLine("AsyncCallback method on ThreadID = {0}", Thread.CurrentThread.GetHashCode()); Stream s = (Stream)ar.AsyncState; s.EndWrite(ar); s.Close(); } }