我正在創建一個Windows窗體應用程序,我選擇一個包含多個* .txt文件的文件夾。它們的長度可能從幾千行(kB)到五千萬行(1GB)不等。代碼的每一行都有三個信息。日期在long中,int中的位置id和float中的值全部用分號(;)分隔。我需要計算所有這些文件中的最小值和最大值,並告訴它是哪個文件,然後是最常見的值。在C#中使用多線程處理多個文件的最佳方式是什麼?
我已經驗證了這些文件並存儲在了數組列表中。我正在打開一個線程來逐個讀取文件,並且我按行讀取數據。它工作正常,但是當有1GB文件時,我的內存不足。我嘗試將值存儲在字典中,其中鍵爲日期,值將是包含從文件名旁邊加載的所有信息的對象。我看到我無法使用字典,因爲在大約6M的值處,我用完了內存。所以我應該在多線程中做到這一點。我雖然可以運行兩個線程,一個讀取文件並將信息放入某種容器中,另一個線程讀取並執行計算,然後刪除容器中的值。但我不知道哪個容器可以做這樣的事情。此外,我需要計算最頻繁的值,因此需要將它們存儲在某處,這會將我引導回某種字典,但我已經知道我將耗盡內存。我對線程也沒有太多經驗,所以我不知道什麼是可能的。這是我到目前爲止的代碼:
GUI:
namespace STI {
public partial class GUI : Form {
private String path = null;
public static ArrayList txtFiles;
public GUI() {
InitializeComponent();
_GUI1 = this;
}
//I run it in thread. I thought I would run the second
//one here that would work with the values inputed in some container
private void buttonRun_Click(object sender, EventArgs e) {
ThreadDataProcessing processing = new ThreadDataProcessing();
Thread t_process = new Thread(processing.runProcessing);
t_process.Start();
//ThreadDataCalculating calculating = new ThreadDataCalculating();
//Thread t_calc = new Thread(calculating.runCalculation());
//t_calc.Start();
}
}
}
ThreadProcessing.cs
namespace STI.thread_package {
class ThreadDataProcessing {
public static Dictionary<long, object> finalMap = new Dictionary<long, object>();
public void runProcessing() {
foreach (FileInfo file in GUI.txtFiles) {
using (FileStream fs = File.Open(file.FullName.ToString(), FileMode.Open))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs)) {
String line;
String[] splitted;
try {
while ((line = sr.ReadLine()) != null) {
splitted = line.Split(';');
if (splitted.Length == 3) {
long date = long.Parse(splitted[0]);
int location = int.Parse(splitted[1]);
float value = float.Parse(splitted[2], CultureInfo.InvariantCulture);
Entry entry = new Entry(date, location, value, file.Name);
if (!finalMap.ContainsKey(entry.getDate())) {
finalMap.Add(entry.getDate(), entry);
}
}
}
GUI._GUI1.update("File \"" + file.Name + "\" completed\n");
}
catch (FormatException ex) {
GUI._GUI1.update("Wrong file format.");
}
catch (OutOfMemoryException) {
GUI._GUI1.update("Out of memory");
}
}
}
}
}
}
,並在我把值在各條線上物體: Entry.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace STI.entities_package {
class Entry {
private long date;
private int location;
private float value;
private String fileName;
private int count;
public Entry(long date, int location, float value, String fileName) {
this.date = date;
this.location = location;
this.value = value;
this.fileName = fileName;
this.count = 1;
}
public long getDate() {
return date;
}
public int getLocation() {
return location;
}
public String getFileName() {
return fileName;
}
}
}
TL; DR; [MCVE](http://stackoverflow.com/help/mcve) – Amit
多線程當然不會幫你在這裏,因爲引入更多的線程並不會奇蹟般地爲你的進程增加更多的內存。編輯問題,以便刪除任何提及的多線程。也刪除GUI代碼,因爲這不是問題。 – Dialecticus
現代計算機擁有大量內存,現在用完內存是一個相當愚蠢的問題。一個terabyte很容易來,也不花任何錢。 Project + Properties,Build選項卡,將平臺目標設置更改爲AnyCPU,在看到它時取消「首選32位」選項。你不喜歡它。 –