编辑:这似乎是一个令人难以置信的点,所以我会把它弄清楚:

我不是使用它来同步。仅仅是为了杀死长期运行的任务,当它们不再变得必要 /理想时。
假设: :假设这些螺纹只需写入控制台(例如:“线程1”),睡一个随机长度,然后退出。如果他们流产,我希望他们通知我另一个控制台写(例如:“线程1中止”)。我希望能够跳跃 直的 如果我在运行之前尝试中止代码,则没有任何机会执行其正常功能。如果在正常功能中流产,它当然会同时打印。


我希望在ASP网站上运行.NET 2.0的带有Visual Studio 2008的ASP网站(不知道所有内容,但这是有多少),但它们可能已经流产清洁代码,我希望按顺序运行。无论他们的任务多远,都应该运行。所以我做了这样的线程:

Thread t = new Thread(delegate() {
   try { 
      /* do things */ 
      System.Diagnostics.Debug.WriteLine("try");
   }
   catch (ThreadAbortException) {
      /* cleanup */ 
      System.Diagnostics.Debug.WriteLine("catch");
   }
});

现在,如果我想逐步中止一组线程,那么以后可能仍然需要清理。浏览MSDN意味着您可以.abort()尚未启动的线程,然后.start()它,此时它将收到异常并正常执行。或者,您可以.join()中止的线程等待它完成流产。大概您可以将它们结合在一起。

http://msdn.microsoft.com/en-us/library/ty8d3wta(v=vs.80).aspx
要等到线程中止,您可以在调用中止方法后在线程上调用JOIN方法,但是不能保证等待将结束。
如果在尚未启动的线程上调用流产,则在调用启动时,线程将中止。如果在被阻塞或正在睡觉的线程上调用中止,则该线程被中断然后流产。

现在,当我调试并介绍此代码时:

t.Abort(); // ThreadState == Unstarted | AbortRequested
t.Start(); // throws ThreadStartException: "Thread failed to start."
// so I comment it out, and
t.Join(); // throws ThreadStateException: "Thread has not been started."

我绝对不会看到任何输出,也不会在尝试或捕获块上进行任何断点。
奇怪的是,ThreadStartException并未将其列为可能的.start(),从这里: http://msdn.microsoft.com/en-us/library/a9fyxz7d(v=vs.80).aspx (或任何其他版本)

我知道可以通过拥有一个启动参数来避免这种情况,该参数指出该线程是否应跳到清理代码,并过度撤销中止呼叫(这可能是我要做的)。和我 可以 .START()螺纹,然后.abort()it。但是,由于不确定的时间可能会在.start和.babort之间经过,因此我正在考虑它不可靠,并且文档似乎说我的原始方法应该起作用。

我想念什么吗?文档错误吗?

编辑:OW。而且您无法在非参数化线程(start)上调用.start(param)。除了反复试验外,是否有办法找出线程是否已被参数化?我看到一个私人m_delegate,但没有公开...

有帮助吗?

解决方案

使用...

t.Abort();
t.Start();

... threadstartexcpetion的innerexception将包含threadabortexeption,就像MSDN所述:((如果在尚未启动的线程上调用流产,则该线程将在启动时流产)

如果您执行...

t.Start();
t.Abort();

...螺纹促进感受可能永远不会发生,因为线程没有时间在中断之前就没有时间开始。

如果您测试类似...

t.Start();
Thread.Sleep(100);
t.Abort();

...“清理”代码应始终执行。

如果您需要执行清理代码,即使该线程尚未开始做任何可能的解决方案,将与中止调用一起启动清理方法。

此外,您应该尝试避免中止线程并使用不同的技术(http://msdn.microsoft.com/en-us/library/ms228964.aspx)

其他提示

我意识到文档对您暗示,但这不是发生的事情。如果您中止线程然后启动该线程,它将永远不会以任何方式执行。 CLR足够聪明,可以知道,线程不稳定是一项不稳定的业务,因此不容错过完全跳过线程执行的机会。

也许将您的清理代码变成子例程。如果父线程中止或知道中止,它将明确调用清理代码。

请记住,在流中止线程后,.NET的“清理”概念是卸载执行中止线程的组件的应用程序。这是另一种说法“不要期望这会很好地清理”。您首先应该始终寻求不需要流产线程的设计。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top