假设下面的方法被.net 4应用程序中的不同线程调用了几千次.处理这种情况的最佳方法是什么?了解磁盘是这里的瓶颈,但我希望WriteFile()方法快速返回.
数据可以高达几MB.我们在谈论线程池,TPL等吗?
public void WriteFile(string FileName, MemoryStream Data)
{
try
{
using (FileStream DiskFile = File.OpenWrite(FileName))
{
Data.WriteTo(DiskFile);
DiskFile.Flush();
DiskFile.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Run Code Online (Sandbox Code Playgroud)
如果你想快速返回而不是真的关心操作是同步的,那么你可以在内存Queue中创建某种类型的写入请求,而当Queue没有填满时你可以快速从方法返回.另一个线程将负责调度Queue和写入文件.如果你WriteFile被调用并且队列已满,你将不得不等到你可以排队并且执行将再次变为同步,但是这样你可以有一个大的缓冲区,所以如果进程文件写请求不是线性的,而是更尖刻的(与写入文件调用之间的暂停峰值)这种变化可以看作是对性能的改进.
更新: 为你做一个小图片.请注意,瓶颈始终存在,您可以做的就是使用队列优化请求.请注意,队列有限制,所以当它填满时,你不能将文件队列成inst,你必须等待,因此该缓冲区中也有一个空闲空间.但是对于图片中呈现的情况(3个桶请求),显而易见的是,您可以快速将桶放入队列并返回,而在第一种情况下,您必须逐个执行此操作并阻止执行.
请注意,您永远不需要同时执行多个IO线程,因为它们都将使用相同的瓶颈,如果您尝试并行处理这个问题就会浪费内存,我相信2到10个线程顶部将轻松占用所有可用的IO带宽,也将限制应用程序内存使用量.

既然您说文件不需要按顺序写入,也不需要立即写入,那么最简单的方法是使用Task:
private void WriteFileAsynchronously(string FileName, MemoryStream Data)
{
Task.Factory.StartNew(() => WriteFileSynchronously(FileName, Data));
}
private void WriteFileSynchronously(string FileName, MemoryStream Data)
{
try
{
using (FileStream DiskFile = File.OpenWrite(FileName))
{
Data.WriteTo(DiskFile);
DiskFile.Flush();
DiskFile.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Run Code Online (Sandbox Code Playgroud)
TPL 在内部使用线程池,即使对于大量任务也应该相当高效。