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块,t2也不会抛出任何错误。这里发生了什么?

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

请帮忙。提前致谢。


编辑:
感谢大家的帮助。我找到了答案,它是

一个无限循环。

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

4

2 回答 2

0

我不知道这是否是你的问题....

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

于 2012-06-01T03:00:49.053 回答
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.");
                }
            }
于 2012-06-01T03:58:45.463 回答