C# 用FileStream.WriteAsync 异步读文件 调用线程还是被阻塞了。

在用FileStream WriteAsync方法(BeginWrite方法也是一样)的异步写文件时、
如下代码。实际上调用这段代码的时候,还是被阻塞了。

 FileStream stream = new FileStream("in.txt", FileMode.OpenOrCreate,
                                    FileAccess.ReadWrite, FileShare.ReadWrite, 1024, FileOptions.Asynchronous);
            byte[] byteData = new byte[80961024 * 4];
            Task task = stream.WriteAsync(byteData, 0, byteData.Length);

如果把这个FileStream绑定到一个StreamWriter上,用StreamWriter的WriteAsync方法倒是能异步,不会阻塞。

FileStream stream = new FileStream("in.txt", FileMode.OpenOrCreate,
                                    FileAccess.ReadWrite, FileShare.ReadWrite, 1024, FileOptions.Asynchronous);
 char[] byteData = new char[80961024 * 4];

            var sw = new StreamWriter(stream);

            Task task = sw.WriteAsync(byteData, 0, byteData.Length);

求大神解惑

估计是没有绑在一起同步造成的

又做了一个测试,把FileStream构造函数中的 buffersize大小由 1024 改成 80961024 * 4 也就是 byteData.Length 。这样看起来没有阻塞,而且
加上await之后也是立即就返回了结果,基本上是秒写。

小弟猜测这样实际是直接一次就把byteData 里面的内容复制到 stream 的缓冲区了,这些应该都是在内存里的操作,所以速度很快。而FileStream的WriteAsync函数是当 byteData里的东西全到它的缓冲区了就返回,从缓冲区到磁盘里的操作不用你在关心了,它自己解决。

小弟也不知道 write 的操作到底是具体是怎样,猜测是 当缓冲区小于要写的文件大小时,WriteAsync 应该是要一边从内存byteData里拿(不这样还能怎么办?),一边往磁盘里写的。如果这个操作确实是在另一个线程(或者DMA不占CPU)执行的话,又怎么会把调用它的线程阻塞死呢?

完整代码如下:await之后函数本应该立即返回到Mai函数中,但是并没有。

 static void Main(string[] args)
{
        ThreadPool.SetMaxThreads(1000, 1000);
        ThreadPoolMessage("Main");
        WriteAsync();
        ThreadPoolMessage("something");

        Console.ReadKey();
}

static async void WriteAsync()
{
        FileStream stream = new FileStream("out.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, 1024 , FileOptions.Asynchronous);
        ThreadPoolMessage("begin");

        //char[] charData = new char[1024 * 1024 * 50];
        //var sw = new StreamWriter(stream);
        //await sw.WriteAsync(charData, 0, charData.Length);

        byte[] byteData = new byte[1024 * 1024 * 500];
        await stream.WriteAsync(byteData, 0, byteData.Length);

        ThreadPoolMessage("end");
        for (int i = 0; i < 10; i++) Console.WriteLine(i);
}

static void ThreadPoolMessage(string data)
{
        int a, b;
        ThreadPool.GetAvailableThreads(out a, out b);
        string message = string.Format("{0}\n  CurrentThreadId is {1}\n  " +
                                "WorkerThreads is:{2}  CompletionPortThreads is :{3}",
                                data, Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());
        Console.WriteLine(message);
}

http://download.csdn.net/download/qq_26245325/9968711

StreamWriter是专门独立的一个文件流写入类,filestream的异步写入可能并不是以流的形势写入。