我有一个 wpf 应用程序,我们称它为 A-app
。 A-app
使用后台 worker 运行异步 B-method
。 B-method
位于不同的项目中,它为 B-method
init 部分创建了几个线程。
用户可以要求运行B-method
,也可以要求取消运行并重新启动。
问题在于,如果它在初始时间被取消,则运行 B-method
的后台工作程序将被取消,但线程不会。
重新启动会创建更多线程,这些线程无法与之前运行的线程同时工作,这会导致一些错误。
Threads 方法主要是等待。
如何停止 B-method
并取消它创建的线程?
不同的 AppDomain 有什么帮助吗? (而不是关闭整个应用程序域?)如果是,那应该怎么做? 有没有更好的办法?
更多详情:
- B 方法在某些设备(可能很多)上运行测试。该方法的初始化是连接到设备 - i/o - 所以大部分时间都花在等待上(这就是我们决定使连接初始化并行的原因)。尝试从 2 个不同的线程连接到同一设备可能会导致问题.
最佳答案
我建议您根本不要创建线程,而是使用 TaskScheduler 并使用并行任务库:
http://msdn.microsoft.com/en-us/library/dd997402%28v=vs.110%29.aspx
TaskScheduler 本身是 ThreadPool 的包装器,它处理线程。它甚至可以执行 WorkStealing、Task Inling 等功能。
最好从这里开始:http://msdn.microsoft.com/en-us/library/dd997402%28v=vs.110%29.aspx
另一种方法是使用 CancalletionToken 启动任务,这使您能够取消任务。看这里:http://msdn.microsoft.com/en-us/library/dd537607%28v=vs.110%29.aspx
编辑:好的,没有 TPL,阻塞线程。这基本上只剩下 Thread.Abort。 这是乱七八糟的,但是没有完美的世界,所以把Form想象成Application A,ClassB就是Application B:
public partial class MainWindow : Window
{
Thread _threadA;
Thread _threadB;
Thread _threadC;
ClassB b1 = new ClassB();
ClassB b2 = new ClassB();
ClassB b3 = new ClassB();
public MainWindow()
{
InitializeComponent();
_threadA = new Thread(() => b1.DoSomeWork("A"));
_threadB = new Thread(() => b2.DoSomeWork("B"));
_threadC = new Thread(() => b3.DoSomeWork("C"));
}
private void btnStartWork_Click(object sender, RoutedEventArgs e)
{
_threadA.Start();
_threadB.Start();
_threadC.Start();
}
private void btnStopThreadA_Click(object sender, RoutedEventArgs e)
{
AbortThreadA();
}
private void btnStopThreadB_Click(object sender, RoutedEventArgs e)
{
AbortThreadB();
}
private void btnStopThreadC_Click(object sender, RoutedEventArgs e)
{
AbortThreadC();
}
private void AbortThreadA()
{
_threadA.Abort();
}
private void AbortThreadB()
{
_threadB.Abort();
}
private void AbortThreadC()
{
_threadC.Abort();
}
private void btnStopAll_Click(object sender, RoutedEventArgs e)
{
AbortThreadA();
AbortThreadB();
AbortThreadC();
}
}
class ClassB
{
public void DoSomeWork(string threadIdentifier)
{
try
{
string preWorkString = "Work work Okeydokey. Thread: " + threadIdentifier;
string postWorkString = "Job's Done. Thread: " + threadIdentifier;
while (true)
{
System.Diagnostics.Debug.WriteLine(preWorkString);
Thread.Sleep(5000);
System.Diagnostics.Debug.WriteLine(postWorkString);
}
}
catch (ThreadAbortException)
{
System.Diagnostics.Debug.WriteLine("Thread aborted. Thread: " + threadIdentifier);
Thread.ResetAbort();
}
}
}
需要 ResetAbort,否则错误会冒泡。
这是一个可能的解决方案吗?
关于c# - 如何强制关闭运行它自己的线程的后台 worker ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25160604/