我希望有人可以帮助我,如果有关于使用多个线程/任务写入文件的问题。请参阅下面的代码示例...
AddFile返回一个包含值的blos数组,blobNumber,blob内的偏移量以及写入blob的数据大小
public long[] AddFile(byte[] data){
long[] values = new long[3];
values[0] = WorkingIndex = getBlobIndex(data); //blobNumber
values[1] = blobFS[WorkingIndex].Position; //Offset
values[2] = length = data.length; //size
//BlobFS is a filestream
blobFS[WorkingIndex].Write(data, 0, data.Length);
return values;
}
因此,我想在foreach循环中使用AddFile函数,如下所示。
List<Task> tasks = new List<Task>(System.Environment.ProcessorCount);
foreach(var file in Directory.GetFiles(@"C:\Documents"){
var task = Task.Factory.StartNew(() => {
byte[] data = File.ReadAllBytes(file);
long[] info = blob.AddFile(data);
return info
});
task.ContinueWith(// do some stuff);
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray);
return result;
我可以想象,由于Write函数尚未完成写入file1而另一个任务正在同时写入file2,因此文件将在blob中相互覆盖的方式完全失败。
那么解决这个问题的最佳方法是什么?也许使用异步写入函数......
非常感谢您的帮助! 亲切的问候, Martijn
答案 0 :(得分:1)
我的建议是不并行运行这些任务。磁盘IO可能是任何基于文件的操作的瓶颈,因此并行运行它们只会导致每个线程被阻塞访问磁盘。最终,你很可能会发现你编写的代码运行速度明显慢于串行运行代码。
是否有特殊原因要求并行使用这些?你可以串行处理磁盘写入而只是在不同的线程上调用ContinueWith()
吗?这样做有利于消除您发布的问题。
编辑:您的for
循环的简单重新实现示例:
foreach(var file in Directory.GetFiles(@"C:\Documents"){
byte[] data = File.ReadAllBytes(file); // this happens on the main thread
// processing of each file is handled in multiple threads in parallel to disk IO
var task = Task.Factory.StartNew(() => {
long[] info = blob.AddFile(data);
return info
});
task.ContinueWith(// do some stuff);
tasks.Add(task);
}