无法在Silverlight中终止工作线程

4

我正在开发一个多线程的Silverlight应用程序。

该应用程序有两个线程:主/UI线程和后台工作线程。

UI线程应该能够像这样终止后台线程:

private Thread executionThread;

....

executionThread = new Thread(ExecuteStart);
executionThread.Start();

....

executionThread.Abort(); // when the user clicks "Stop"

最后一行引发了异常:

MethodAccessException:尝试访问方法失败:System.Threading.Thread.Abort()

有什么想法吗?为什么我无法在Silverlight中终止线程?

谢谢, Naimi


这也可能会有所帮助:http://msdn.microsoft.com/en-us/magazine/cc765416.aspx - MichaelGG
3个回答

6

不必手动创建线程,您可以考虑使用BackgroundWorker类。

该类内置了当WorkerSupportsCancellation=true时取消异步操作的功能。

请参阅MSDN上的完整示例,了解如何在Silverlight中使用BackgroundWorker。


BackgroundWorker 需要工作线程不断检查取消操作。是否有一种方法可以立即强制终止工作线程? - ANaimi
我建议你不要追求“强制”工作线程退出的想法。取消工作线程使其返回线程池是正确的方法。使用volatile bool或ManualResetEvent并不能比BackgroundWorker更立即地“强制”取消。 - Peter McG
不幸的是,在某些情况下,调用内置函数可能需要很长时间,并且它们没有超时机制。因此,停止它们的唯一方法是调用Thread.Abort。例如,Regex类...https://dev59.com/lmDVa4cB1Zd3GeqPhuZs.但请注意,只有在运行具有提升信任的Silverlight 5应用程序时才能使用Thread.Abort而不会出现安全异常。 - Steve Wortham

4

这已经有文档记录了,详见Thread.Abort()

该成员带有SecurityCriticalAttribute属性,仅限.NET Framework for Silverlight类库内部使用。使用该成员的应用程序代码会抛出MethodAccessException异常。

您可以使用ManualResetEvent(一种线程安全的通信方法)来向后台线程发出停止信号。

以下是后台线程的示例代码:

if (!shouldStop.WaitOne(0)) 
// you could also sleep 5 seconds by using 5000, but still be stopped 
// after just 2 seconds by the other thread.
{
    // do thread stuff
}
else
{
    // do cleanup stuff and exit thread.
}

0

由于Silverlight代码是通过互联网传输的,因此通常是不受信任的,并且其执行受到更多限制,正如Davy所指出的那样。 相反,在后台线程的规范类中实现一个布尔型退出标志,以便您可以提高此标志并使用Thread.Join()。


布尔标志不被推荐使用,它们并不真正是线程安全的。 - Davy Landman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接