C#线程池:一个线程阻塞其他线程?

3
我有一个C#控制台应用程序,其中有一个线程池。在线程池中,有一个类执行一个连续的方法(直到它运行了一定的时间或者知道何时停止)。该方法连接到一个HttpWebResponse流并持续读取它。
问题在于,在短时间内,所有线程都在执行它们的任务,但之后只有一个线程会不断地显示输出,而其他线程则在等待该线程。
以下是每个线程执行的方法。
function void ReadStream()
        byte[] buf = new byte[8192];

        String domain = streamingUrl

        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(domain);
        HttpWebResponse response = (HttpWebResponse)
        request.GetResponse();

        Stream resStream = response.GetResponseStream();

        string tempString = null;
        int count;
        do
        {
            // fill the buffer with data
            count = resStream.Read(buf, 0, buf.Length);

            if (count != 0)
            {
                tempString = Encoding.ASCII.GetString(buf, 0, count);

                try
                {
                    mySqlManager.SaveResult(tempString);

                    Console.WriteLine("Been here");
                    Thread.Sleep(1000);
                }
                catch (Exception e)
                {
                }
            }
        }
        while (count > 0);
    }

当应用程序处于其他线程正在等待一个线程的状态时,您可以在调试器中点击“Break All”按钮。这可能会向您展示这些线程正在等待什么。此外,请检查空catch块中是否有任何异常,这可能会隐藏一些有趣的信息。 - Chris O
你不应该使用 new 关键字创建新的 StreamReader 实例吗? - Anirudh Ramanathan
2个回答

5
首先,您应该在 using 块中包装 responseresStream,以确保它们被正确处理。
其次,在我的看法中,将 长时间运行的线程 放入 ThreadPool 不是最好的方法。 ThreadPool 类的想法是它允许您排队相对较小的操作,而为每个操作生成新线程将是浪费的。 如果您有需要花费大量时间才能运行的操作,我建议实际上为每个操作创建专用的 Thread 对象。

我怀疑线程池中的Thread.Sleep(1000)引起了这个问题。我也遇到了同样的问题。问题是为什么线程池线程会阻塞其他线程? - Rajan Panneer Selvam

0
你应该在调试器中断点处进行调试,找出每个线程停止的位置,但我猜罪魁祸首是:

mySqlManager.SaveResult(tempString);

mySqlManager 似乎是一个类属性,这意味着您需要特别注意线程安全性。确保 SaveResult() 是线程安全的;如果不是,则需要使用锁定使您对 SaveResult() 的调用变得线程安全。

祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接