【问题标题】:Write file need to optimised for heavy traffic part 3写入文件需要针对大流量进行优化第 3 部分
【发布时间】:2012-07-16 15:09:33
【问题描述】:

这个问题是前2部分的延续,有兴趣知道我从哪里来的可以参考第1部分和第2部分,但不是必须的。

write file need to optimised for heavy traffic

Write file need to optimised for heavy traffic part 2

现在我有一个工作的sn-p,相关部分如下:

    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();
        }

上面的 sn-p 工作正常,并且没有错误。每次写入输出大约 8KB 的数据。

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

基本上我有 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,而且写入的频率太高了(比我的单线程程序)。有人可以启发我并指出我的程序有什么问题吗?非常感谢

【问题讨论】:

  • 正如@channs 指出的那样,如果您之前的任何问题都得到了正确回答,您应该将这些答案标记为已接受。
  • 你为什么不在codereview.stackexchange.com上审查你的代码
  • 结合 static 和 Streams 并不是一个好主意。当你结合静态和多线程时,你在乞求坏事发生。你在这里的东西是错误的。废弃它并重新考虑多线程。
  • @Austin Salonen 我尝试将我的编码更改为实例,但我的输出更糟糕,我写入了一个 0 KB 的文件,我只是不明白。谁能帮帮我?
  • @Jodrell,对不起,我现在回去了,并标记了我以前的所有问题,我是 stackoverflow 的新手,不知道正确的做法

标签: c# multithreading performance io


【解决方案1】:

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

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

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

这段代码的作用是:

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

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

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

【讨论】:

  • 我输入的内容几乎完全相同。 +1
猜你喜欢
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多