我已經構建了此代碼來並行處理大量字符串之間的字符串比較,以便更快。轉儲多線程訪問ConcurrentBag文件不夠快
我已經使用了ConcurrentBag,所以所有線程(任務)都可以寫入線程安全集合。然後我將這個集合轉儲到一個文件中。
我遇到的問題是我轉儲到文件的ConcurrentBag<string> log
的填充速度比寫入文件的速度要快。所以我的程序不斷消耗越來越多的內存,直到內存耗盡。
我的問題是我能做些什麼?改進寫入日誌?暫停任務,直到ConcurrentBag被轉儲,然後恢復任務?什麼是最快的選擇?
下面是代碼:
CsvWriter csv = new CsvWriter(@"C:\test.csv");
List<Bailleur> bailleurs = DataLoader.LoadBailleurs();
ConcurrentBag<string> log = new ConcurrentBag<string>();
int i = 0;
var taskWriteToLog = new Task(() =>
{
// Consume the items in the bag
string item;
while (true) // (!log.IsEmpty)
{
if (!log.IsEmpty)
{
if (log.TryTake(out item))
{
csv.WriteLine(item);
}
else
Console.WriteLine("Concurrent Bag busy");
}
else
{
System.Threading.Thread.Sleep(1000);
}
}
});
taskWriteToLog.Start();
Parallel.ForEach(bailleurs, s1 =>
{
foreach (Bailleur s2 in bailleurs)
{
var lcs2 = LongestCommonSubsequenceExtensions.LongestCommonSubsequence(s1.Name, s2.Name);
string line = String.Format("\"LCS\",\"{0}\",\"{1}\",\"{2}\"", s1.Name, s2.Name, lcs2.Item2);
log.Add(line);
// Console.WriteLine(line);
var dic = DiceCoefficientExtensions.DiceCoefficient(s1.Name, s2.Name);
line = String.Format("\"DICE\",\"{0}\",\"{1}\",\"{2}\"", s1.Name, s2.Name, dic);
log.Add(line);
// Console.WriteLine(line);
}
i++;
Console.WriteLine(i);
});
public class CsvWriter
{
public string FilePath { get; set; }
private FileStream _fs { get; set; }
private StreamWriter _sw { get; set; }
public CsvWriter2(string filePath)
{
FilePath = filePath;
_fs = new FileStream(FilePath, FileMode.Create, FileAccess.Write);
_sw = new StreamWriter(_fs);
}
public void WriteLine(string line)
{
_sw.WriteLine(line);
}
}
太棒了!它的作品非常好!非常感謝 –
@ Arno2501知道,當你需要向相反的方向前進時,這個類也非常有用,一個編寫器放入包中,許多線程都調用'GetConsumingEnumberable()'在可用時進行工作。 'Parallel.ForEach(myBlockingCollection.GetConsumingEnumberable(),...)'工作得很好,我在使用'IDataReader'的項目中使用它很多,只能由一個線程訪問,但是結果中的工作可以是並行處理。 –
非常有用的信息再次感謝。真棒看到並行處理變得越來越簡單:-) –