簡體   English   中英

多線程將byte []寫入文件

[英]Multithread Write byte[] into file

如果對使用多個線程/任務寫入文件有疑問,我希望有人能為我提供幫助。 請參閱下面的代碼示例...

AddFile返回一個由long組成的數組,其中包含值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中相互覆蓋。

那么解決這個問題的最佳方法是什么? 也許使用異步寫入功能...

您的幫助將不勝感激! 親切的問候,馬丁

我的建議是不要並行運行這些任務。 磁盤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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM