是什么导致线程挂起,即使在20小时后也不会抛出任何东西

时间:2012-06-01 02:54:57

标签: c# multithreading .net-4.0

我在线程内部有线程,最后一个子线程只挂起,现在不会抛出任何东西20小时。我的代码是这样的:

bool end = false;

var t1 = new Thread(() =>
{
    // ...

    var t2 = new Thread(() =>
    {
        try
        {
            foreach(Data data in datas2)
            {
                foreach(SubData subdata in data.SubDatas)
                {
                    var t3 = new Thread(() =>
                    {
                        this.SaveData(subdata.RetrieveData());
                    }); t3.Start();

                    if (!t3.Join(1800000))
                    {
                        t3.Abort();
                        throw new TimeoutException("The execution of method is taking too long.");
                    }
                }
            }
        } catch { throw; }
        finally { end = true; }
    }); t2.Start();
}); t1.Start();

它永远不会通过finally的{​​{1}}块,并且不会抛出任何错误。这里发生了什么?

我的代码在C#,框架4中,在Visual Studio 2010 Pro中构建。

请帮忙。提前谢谢。


修改
谢谢大家的帮助。我找到了答案,它是

  

无限循环。

对于这个愚蠢的错误,我们的生产停止了一个星期。啊。似乎我们的系统上有一个验证只为某些数据创建了一个无限循环。感谢大家热心解决这个问题。

2 个答案:

答案 0 :(得分:0)

我不知道你的情况是否有问题......

然而,Thread.Abort引发了一个异常(一个特殊的异常,即使你抓住它,一旦捕获并最终完成它将自动重新抛出自己,除非你清除中止)。如果SaveData和RetriveData中的代码捕获异常,然后在catch中或最终被阻塞,它将不会中止。

答案 1 :(得分:0)

我们不知道SaveData或RetrieveData中可能发生了什么。您可能正在进行我们不了解的极长/重复I / O.

此外,我不认为此代码正在执行您认为正在执行的操作。见我的//注意:下面:

            foreach(SubData subdata in data1.SubDatas)
            {
                var t3 = new Thread(() =>
                {
                    this.SaveData(subdata.RetrieveData());
                }); t3.Start();

                // NOTE: Here you are blocking each iteration of T2 
                // while T3 runs.  There is no reason to be running 
                // another thread here- just call SaveData/RetrieveData 
                // from T2.  Additionally, because this is executing in 
                // a double-nested loop, you might be doing this many, 
                // many times.  I'd suggest looking into ThreadPool or TPL.

                if (!t3.Join(1800000))
                {
                    t3.Abort();
                    throw new TimeoutException("The execution of method is taking too long.");
                }
            }