C#处理二进制文件,多线程处理

时间:2010-04-21 09:53:44

标签: c# multithreading binaryreader

我有以下代码处理二进制文件。我想通过使用线程分割处理工作负载,并将二进制文件的每一行分配给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();

3 个答案:

答案 0 :(得分:3)

这对我来说看起来不安全。如果您有多个工作项排队,并且其中两个碰巧同时运行,那么读者的位置可能会在分配和阅读之间轻松改变。

如果你坚持使用线程,你最好读取主线程中的数据并排队生成的字节数组以供读取。涉及从文件中读取每个线程的任何解决方案都将涉及锁定,此时,您根本无法使用线程获得任何内容。

答案 1 :(得分:2)

使用线程来提高文件处理性能非常有意义。在多核CPU上运行时,线程提供更多的CPU周期。这很少是处理文件时缺少的资源。你需要更多的磁盘。当然不是一种选择。

首先进行烟雾测试。重新启动计算机,以使文件不会存储在文件系统缓存中。运行单线程程序并观察CPU负载。 Taskmgr.exe,性能选项卡很适合。如果在100%负载下没有看到一个CPU最大输出,那么添加另一个CPU无法使您的程序更快。

答案 2 :(得分:0)

  

“我觉得它会更好   只传递每行的二进制文件   到PROCESS_Binary_Return_lineData   方法“。

是的,你需要这样做,因为你的代表在重新定位之前可能无法从BinaryReader读取