2012-07-05 103 views
0

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

AddFile返回保持的值多头的排列,blobNumber的斑点和数据写入到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; 

我可以想像,这将完全失败,因为文件将互相覆盖BLOB中由于事实写入功能还没有写完文件1和其他任务在被写入文件2路同一时间。

那么解决这个问题的最好方法是什么?也许使用异步写功能...

您的帮助,将不胜感激! 亲切的问候, 马亭

+1

.NET 4.5将提供异步文件I/O本身,它是更好地保持同步的东西的那一刻(你写无论如何都是同一个物理驱动器,所以操作无法首先进行并行化)。 – Alex

回答

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); 
} 
+0

我只想从我的应用程序中获得最大性能。我需要处理大量的文件,我可以改进的过程中的每一步都希望能够加速这个过程。但是你说得对,这可能会导致I/O瓶颈。你能解释一下你的意思吗?“你可以连续处理磁盘写入操作,只需在不同的线程上调用ContinueWith(),而不是?” TNX! – Martijn

+0

请参阅我的编辑,了解我的意思。 –