我有一个只是放逐的线程..我想知道是谁杀了我的线程,为什么。
我发现我的线程被操作系统杀死了,但我想确认一下,如果可能的话就知道为什么它会被杀死。
至于线程,我可以断言它在死亡前至少执行了40分钟,但它突然在5分钟内死亡。
public void RunWorker()
{
Thread worker = new Thread(delegate()
{
try
{
DoSomethingForALongLongTime();
}
catch(Exception e)
{
//Nothing is never logged :(
LogException(e);
throw e;
}
});
worker.IsBackground = true;
worker.SetApartmentState(System.Threading.ApartmentState.STA);
worker.Start();
}
编辑:寻址答案
想到这些事情就把我带到了这个问题,谁杀了我的线程?
PS。在烛台的客厅里,不是Lady Goldent:)
答案 0 :(得分:20)
各种各样的人(包括我自己,here)指出,在IIS中托管长时间运行的线程是一个坏主意。您的线程将在IIS“工作进程”中运行。这些进程由IIS定期终止(回收),这将导致您的线程死亡。
我建议您尝试关闭IIS工作进程回收,看看是否有所作为。您可以找到更多信息here。
答案 1 :(得分:13)
您的主题可能只是抛出异常。尝试在DoSomethingForALongLongTime
周围放置一个try / catch块,看看它是什么。
更新:之前我没有注意到您是从网络服务器启动的。这可能是一个非常糟糕的主意。特别是,使用从HttpContext.Current
派生的任何信息的单独线程是什么?这将包括Request
,Response
,Session
等,以及页面中的任何信息。
这很糟糕,因为只要请求持续,这些事情就会持续下去。一旦请求结束,它们就会变得无效,至少可以说。
如果您需要从Web应用程序或Web服务中启动长时间运行的线程,那么您应该创建一个简单的Windows服务并在其中托管WCF服务。然后让网页将执行任务所需的所有信息发送到服务。该服务甚至可以使用MSMQ作为传输,这将确保即使服务繁忙也不会丢失任何消息。
答案 2 :(得分:5)
获取更多信息的潜在方法:附加调试器并中断线程终止。根据线程的终止方式,这可能不起作用。
sxe et
以启用线程退出.loadby sos mscorsvr
,.loadby sos mscorwks
或.loadby sos clr
应该有效),然后运行!clrstack
(请参阅!help
对于其他sos命令)如果您从其他线程中获得大量噪音,请在断开后继续编写windbg,如果它不是您关心的线程ID。
修改:如果您认为该流程已在流程中终止,您还可以在TerminateThread
(bp kernel32!TerminateThread
)和ExitThread
上设置断点(bp kernel32!ExitThread
)抓住凶手的堆栈。
答案 3 :(得分:4)
我不知道答案,但有些想法:
<强>更新强>
你说:
此主题由网站创建 服务器,继续运行
如果线程在asp.net内部运行,则可能是当asp.net工作进程回收时线程被杀死,它将定期执行。您可以尝试关闭工作流程回收,看看是否有任何区别。
答案 4 :(得分:4)
您的编辑会显示答案:
这是
管家网络服务器。
您如何主持这些主题? Web服务器环境并非完全用于托管长期生存进程。事实上,它可能被配置为每隔40分钟停止一次失控的站点?
修改强>
要快速修复,最好的机会是设置worker.IsBackground = false;
,因为当前设置为true允许系统终止父线程,而不用等待你的bgw。
另一方面,在ASP.NET应用程序中使用BackgroundWorker没什么意义,它适用于WinForms和WPF。为此创建一个单独的线程会更好,因为您正在更改某些Threads属性。不建议使用ThreadPool(Bgw)线程。
答案 5 :(得分:3)
这个过程可能会终止。那就是worker.IsBackground = true;旨在做,在主线程退出时终止你的线程。
答案 6 :(得分:3)
后台线程只会在前台线程运行时运行。一旦所有前台线程结束,任何仍在运行的后台线程都会中止。
答案 7 :(得分:2)
如果检查异常没有显示任何有用的内容,请将您的线程代码写入关键点的日志文件中。然后,您将能够确切地看到它何时停止工作,并希望为什么。
答案 8 :(得分:2)
一个简单的答案是:“凶手不会留下名片”;)
希望这有帮助。
答案 9 :(得分:2)
您可以尝试在 web.config 中增加 configuration \ system.web \ httpRuntime 的 executionTimeout 值(默认值为110秒in .NET 4.0和90对应于http://msdn.microsoft.com/en-us/library/e1f13641.aspx)。您可以尝试动态更改它Server.ScriptTimeout = 300(请参阅http://www.beansoftware.com/ASP.NET-Tutorials/Long-Operations.aspx)。这个参数不会有帮助,那么我认为你有一个问题,比如从IIS回收线程。如何查看此参数的默认值远小于线程的典型实时时间。我认为,你的问题有另一种性质,但要确定......
为什么要为线程设置公寓状态?您在工作线程中使用哪些COM对象?您是否有一个非托管代码可以完成大部分工作,您还可以插入一些代码?我认为你应该有更多关于SomethingForALongLongTime
能够解决问题的信息。
还有一点建议。你可以在调用SomethingForALongLongTime();
之后插入一行代码,以确保SomethingForALongLongTime
没有异常结束吗?
更新:为了确保您的线程不会被IIS杀死,您可以尝试创建一个SomethingForALongLongTime();
而不是使用线程的进程。
答案 10 :(得分:2)
当您调用RunWorker()时,可以将对线程的引用添加到列表中。一旦检测到你的线程已经死亡,你可以检查线程的状态,也许它会揭示它是如何死亡的。或者,也许它没有死,它只是在等待一些资源(比如连接到数据库)。
List runningThreads = ...
public void RunWorker() {
Thread worker = new Thread(delegate()
..
runningThreads.add(worker);
worker.Start();
}
public void checkThreads() {
for (Thread t : runningThreads) {
Console.WriteLine("ThreadState: {0}", t.ThreadState);
}
}
答案 11 :(得分:1)
它可能会抛出各种无法捕获的异常之一,包括 Stack Overflow 或 Out of Memory 。这些是追踪的最难例外。
此线程运行时内存消耗是什么样的?你可以在它上面使用内存分析器来查看它是否失控?你能在内循环中添加一些日志记录吗?如果你有一个递归方法,添加一个计数器并抛出一个异常,如果它递归不可能的次数。您是否正在使用可能导致大对象堆碎片的大型对象(即使您没有真正出局也会导致内存不足错误)。
答案 12 :(得分:1)
您应该使用大量调试日志来检测DoSomethingForALongLongTime(),这样您就可以找到代码停止执行的位置。或者附加调试器并中断所有第一次机会异常。
答案 13 :(得分:1)
使用AsyncTasks在asp.net中实现长期运行
答案 14 :(得分:1)
尝试使用app域UnhandledException事件:http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx
如果你错过了一些例外,它可能会给你一些信息