1

这个问题是前2部分的延续,任何有兴趣了解我来自哪里的人可以参考第1部分和第2部分,但这不是必需的。

写入文件需要针对大流量进行优化

写入文件需要针对大流量进行优化第 2 部分

现在我有一个工作片段,相关部分如下:

    public static class memoryStreamClass
    {
        static MemoryStream ms1 = new MemoryStream();

        public static void fillBuffer(string outputString)
        {
            byte[] outputByte = Encoding.ASCII.GetBytes(outputString);

            ms1.Write(outputByte, 0, outputByte.Length);

            if (ms1.Length > 8100)
            {
                emptyBuffer(ms1);
                ms1.SetLength(0);
                ms1.Position = 0;
            }
        }

        static void emptyBuffer(MemoryStream ms)
        {
            FileStream outStream = new FileStream("c:\\output.txt", FileMode.Append);

            ms.WriteTo(outStream);
            outStream.Flush();
            outStream.Close();
        }

上面的代码片段工作正常,并且没有错误。它每次写入输出大约 8KB 的数据。

现在我尝试对上述代码进行多线程处理,以提高 IO 写入瓶颈的性能,并出现了问题。下面的片段是我试图尝试的。

基本上我有 2 个相同的 memoryStream,如果说 ms1 已满,它将 ms1 写入文件并在 ms1 写入时切换到 ms2,反之亦然。

    public static class memoryStreamClass
    {
        static MemoryStream ms1 = new MemoryStream();
        static MemoryStream ms2 = new MemoryStream();
        static int c = 1;

        public static void fillBuffer(string outputString)
        {
            byte[] outputByte = Encoding.ASCII.GetBytes(outputString);

            if (c == 1)
            {
                ms1.Write(outputByte, 0, outputByte.Length);

                if (ms1.Length > 8100)
                {
                    c = 2;

                    Thread thread1 = new Thread( () => emptyBuffer(ms1));
                    thread1.Start();

                    ms1.SetLength(0);
                    ms1.Position = 0;
                }
            }
            else
            {
                ms2.Write(outputByte, 0, outputByte.Length);

                if (ms2.Length > 8100)
                {
                    c = 1;

                    Thread thread2 = new Thread(() => emptyBuffer(ms2));
                    thread2.Start();

                    ms2.SetLength(0);
                    ms2.Position = 0;

                }
            }
        }

上面的代码可以编译运行,但是输出写入并不总是8KB,而且写入的频率太高了(比我的单线程程序)。有人可以启发我并指出我的程序有什么问题吗?非常感谢你

4

1 回答 1

1

您的代码严重损坏,您使用两个缓冲区来提高性能的想法几乎可以肯定是过度优化。但是,这段代码有一个明显的问题:

Thread thread1 = new Thread( () => emptyBuffer(ms1));
thread1.Start();

ms1.SetLength(0);
ms1.Position = 0;

这段代码的作用是:

  • 启动一个线程来处理一个缓冲区
  • 立即清除该缓冲区

问题是您的“清晰”代码几乎肯定会在您的线程有机会启动之前执行(因为一般来说,执行方法将在线程上下文更改之前完成)。所以,当你打电话的时候emptyBuffer,你MemoryStream的已经是空的了。

你的静态是个坏主意;如果您要将非静态实例传递给该emptyBuffer方法,然后 set ms1 = new MemoryStream(),您可能会有更好的功能代码。但最终,此代码在概念上存在缺陷,您应该考虑重新设计。

于 2012-07-17T16:58:42.310 回答