我有以下代码处理二进制文件。我想通过使用线程分割处理工作负载,并将二进制文件的每一行分配给ThreadPool中的线程。每行的处理时间很短,但在处理可能包含数百行的文件时,分割工作负载是有意义的。
我的问题是关于BinaryReader和线程安全性。首先,我正在做的事情可以接受。我觉得最好只将每行的二进制文件传递给PROCESS_Binary_Return_lineData方法。
请注意以下代码是概念性的。我正在寻找一个关于此的指导,因为我对多线程的了解还处于起步阶段。也许有更好的方法来实现相同的结果,即每个二进制行的分割处理。
var dic = new Dictionary<DateTime, Data>();
var resetEvent = new ManualResetEvent(false);
using (var b = new BinaryReader(File.Open(Constants.dataFile,
FileMode.Open, FileAccess.Read, FileShare.Read)))
{
var lByte = b.BaseStream.Length;
var toProcess = 0;
while (lByte >= DATALENGTH)
{
b.BaseStream.Position = lByte;
lByte = lByte - AB_DATALENGTH;
ThreadPool.QueueUserWorkItem(delegate
{
Interlocked.Increment(ref toProcess);
var lineData = PROCESS_Binary_Return_lineData(b);
lock(dic)
{
if (!dic.ContainsKey(lineData.DateTime))
{
dic.Add(lineData.DateTime, lineData);
}
}
if (Interlocked.Decrement(ref toProcess) == 0) resetEvent.Set();
}, null);
}
}
resetEvent.WaitOne();
答案 0 :(得分:3)
这对我来说看起来不安全。如果您有多个工作项排队,并且其中两个碰巧同时运行,那么读者的位置可能会在分配和阅读之间轻松改变。
如果你坚持使用线程,你最好读取主线程中的数据并排队生成的字节数组以供读取。涉及从文件中读取每个线程的任何解决方案都将涉及锁定,此时,您根本无法使用线程获得任何内容。
答案 1 :(得分:2)
使用线程来提高文件处理性能非常有意义。在多核CPU上运行时,线程提供更多的CPU周期。这很少是处理文件时缺少的资源。你需要更多的磁盘。当然不是一种选择。
首先进行烟雾测试。重新启动计算机,以使文件不会存储在文件系统缓存中。运行单线程程序并观察CPU负载。 Taskmgr.exe,性能选项卡很适合。如果在100%负载下没有看到一个CPU最大输出,那么添加另一个CPU无法使您的程序更快。
答案 2 :(得分:0)
“我觉得它会更好 只传递每行的二进制文件 到PROCESS_Binary_Return_lineData 方法“。
是的,你需要这样做,因为你的代表在重新定位之前可能无法从BinaryReader读取