1

我有这段代码运行了大约 2 个小时。之后程序停止回答,我在 VS 中暂停它并检查它在哪一行执行。我在 Parallel 语句中停下来,说了一些关于“等待线程加入并停止睡眠”的内容。

很明显,我的多线程经验很少,所以我不知道为什么会这样。我认为进入 while 的线程将被隔离并等待在 foreach 中启动的所有其他线程。

while (true)
        {
        Parallel.ForEach(servers, server => // It stopped here
        {

            Console.WriteLine(string.Format("Checking: {0} Thread: {1}", server.Hostname, Thread.CurrentThread.ManagedThreadId));
            try
            {
               // Do some network stuff
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message.ToString());
            }
        });
}

更新 1

做一些网络工作是在 1500 毫秒内进行一些 UDP 发送和接收超时。我这里也有一些基于实体框架的数据库。所以很可能会出错。但是我仍然不确定是什么原因造成的。如果套接字(我的 UDP 东西和 DB 东西)正在运行并超过超时,它们将引发一个将被“处理”的异常

这还不够吗?我可以为整个线程设置某种超时。如果它还没有加入 5000 毫秒杀死它?

4

2 回答 2

3

“做一些网络工作”将是我看到的第一件事(特别是:它是否有可能无限期地阻塞 - 可能在Read没有发送但没有关闭的流上没有超时)。如果任何“做一些网络工作”代码块,那将阻止整个Parallel.ForEach,因为它不会从每个项目完成.ForEach之前返回。

发现Parallel.ForEach等待连接并不意外(毕竟Parallel.ForEach 是拆分和连接) - 重要的问题是:还发生了什么,即其他线程在做什么。

但是,我还想问一下是否有人只是简单地按下pause了键盘(暂停控制台输出),或者不小心在控制台区域上单击拖动(可以进入复制/粘贴模式,这再次暂停控制台输出)。

于 2012-08-15T06:07:40.827 回答
1

如果您希望这只需要几秒钟,请在没有的情况下运行代码Parallel.ForEach,然后您将能够轻松查看阻塞的内容,因为它都在您的主线程上。

如果您在 VS2010 上执行此操作,那么您还可以通过使用 Visual Studio 中的“并行堆栈”调试窗口来查看发生了什么。见这里:http: //msdn.microsoft.com/en-us/library/dd998398.aspx

如果您没有多线程编程经验,那么我会从一个简单且Thread基于标准的程序开始,并熟悉调试工具(例如,您将需要线程调试窗格),然后再开始使用 Task Parallel 进行调试图书馆 ( Parallel.[...])。

于 2012-08-15T06:29:27.890 回答