多线程将byte []写入文件

时间:2012-07-05 08:20:30

标签: c# multithreading asynchronous filestream

我希望有人可以帮助我,如果有关于使用多个线程/任务写入文件的问题。请参阅下面的代码示例...

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

1 个答案:

答案 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);
}