我有以下处理二进制文件的代码。我希望通过使用线程并将二进制文件的每一行分配给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();发布于 2010-04-21 18:09:50
在我看来,这不是线程安全的。如果您有多个工作项在排队,并且其中两个恰好同时运行,则读取器的位置可以很容易地在分配和阅读之间更改。
如果您坚持使用线程,那么最好读取主线程中的数据,并将生成的字节数组排入队列以供读取。任何涉及每个线程从文件读取的解决方案都将涉及锁定,在这一点上,您根本不能从使用线程中获得任何东西。
发布于 2010-04-21 20:57:22
使用线程来提高文件处理性能很少有意义。当线程在多核CPU上运行时,可以提供更多的CPU周期。这很少是您在处理文件时缺少的资源。您需要更多磁盘。当然,这不是一个选择。
首先进行冒烟测试。重新启动机器,这样文件就不会存储在文件系统缓存中。运行单线程程序并观察CPU负载。Taskmgr.exe,Performance标签对此很有帮助。如果你没有看到一个CPU在100%的负载下达到最大值,那么添加另一个CPU并不能让你的程序更快。
发布于 2010-04-21 18:09:33
“我有一种感觉,只将每行的二进制文件传递给PROCESS_Binary_Return_lineData方法会更好。”
是的,您需要这样做,因为在重新定位之前,您的委托可能无法从BinaryReader中读取数据
https://stackoverflow.com/questions/2681849
复制相似问题