これは、非同期で実行したいコードを実際に同期して実行するためのすべての方法をリストしたナレッジベースの記事です。
非同期ディスクI/Oは、Windows NT、Windows 2000、およびWindowsXPでは同期として表示されます
リストにあるものはあなたの状況に当てはまりますか?
.NET 4.5のReadAsyncメソッドで同じ動作を実装しようとしましたか?
私はMSDNから引用しています:
.NET Framework 4以前のバージョンでは、BeginReadやEndReadなどのメソッドを使用して非同期I/O操作を実装する必要があります。これらのメソッドは、レガシーコードをサポートするために.NETFramework4.5でも引き続き使用できます。ただし、ReadAsync、WriteAsync、CopyToAsync、FlushAsyncなどの新しい非同期メソッドを使用すると、非同期I/O操作をより簡単に実装できます。
編集 ICH10とWindows7を搭載したOCZVertex2で256MBのファイルを使用して問題を再現しています。ファイルを生成し、PCを再起動してファイルキャッシュをクリアしてから、同じファイルを読み取ってみてください。
using System;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
string fileName = @"C:\Temp\a1.txt";
int arraySize = 512 * 1024 * 1024;
var bytes = new byte[arraySize];
new Random().NextBytes(bytes);
// This prints false, as expected for async call
var callback = new AsyncCallback(result =>
Console.WriteLine("Completed Synchronously: " + result.CompletedSynchronously));
try
{
// Use this method to generate file...
//WriteFileWithRandomBytes(fileName, arraySize, bytes, callback);
Console.WriteLine("ReadFileAsync invoked at " + DateTimeOffset.Now);
var task = ReadFileAsync(fileName);
Console.WriteLine("ReadFileAsync completed at " + DateTimeOffset.Now);
Task.WaitAll(task);
Console.WriteLine("Wait on a read task completed at " + DateTimeOffset.Now);
}
finally
{
if (File.Exists(fileName))
File.Delete(fileName);
}
}
private static void WriteFileWithRandomBytes(string fileName, int arraySize, byte[] bytes, AsyncCallback callback)
{
using (var fileStream = new FileStream(fileName,
FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 128 * 1024, FileOptions.Asynchronous))
{
Console.WriteLine("BeginWrite invoked at " + DateTimeOffset.Now);
var asyncResult = fileStream.BeginWrite(bytes, 0, arraySize, callback, null);
Console.WriteLine("BeginWrite completed at " + DateTimeOffset.Now);
// completes in 6 seconds or so... Expecting instantaneous return instead of blocking
// I expect runtime to block here...
Task.WaitAll(Task.Factory.FromAsync(asyncResult, fileStream.EndWrite));
// or at least when flushing the stream on the following end-curly
}
}
private static Task<int> ReadFileAsync(string filePath)
{
FileInfo fi = new FileInfo(filePath);
byte[] buffer = new byte[fi.Length];
var file = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None, 64 * 1024, FileOptions.Asynchronous);
Task<int> task = Task<int>.Factory.FromAsync(file.BeginRead, file.EndRead, buffer, 0, buffer.Length, null);
return task.ContinueWith(t =>
{
file.Close();
Console.WriteLine("Done ReadFileAsync, read " + t.Result + " bytes.");
return t.Result;
});
}
}
}
他のすべてが失敗した場合、ここにアンマネージAPIドキュメントへの参照があります。