如何强制关闭运行自己线程的后台工作线程
本文关键字:线程 后台 工作 自己 运行 何强制 | 更新日期: 2023-09-27 18:16:43
我有一个wpf应用程序,我们叫它A-app
。A-app
运行异步B-method
,有一个后台worker。B-method
位于不同的项目中,它为B-method
init部分创建了几个线程。
用户可以请求运行B-method
,也可以请求取消运行和重新启动。问题是,如果它在初始化时间被取消,运行B-method
的后台工作线程被取消,但线程没有。重新启动会创建更多的线程,这些线程不能与之前运行的线程同时工作,并且会产生一些错误。
Threads方法主要是等待。
我如何停止B-method
并取消它创建的线程?
不同的AppDomain是否有帮助?(然后关闭整个应用领域?)如果是,应该怎么做?有没有更好的办法?
- b方法在某些设备(可能是许多)上运行测试。方法的初始化是连接到设备——I/O——所以大部分时间都花在等待上(这就是我们决定让连接初始化并行的原因)。试图从两个不同的线程连接到同一个设备可能会导致问题。
我建议你根本不要创建线程,而是使用TaskScheduler并使用并行任务库:
http://msdn.microsoft.com/en-us/library/dd997402%28v=vs.110%29.aspxTaskScheduler本身是ThreadPool的包装器,它处理线程。它甚至可以做像偷工作,任务嵌入等事情。
最好从这里开始: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想象成应用程序A, ClassB是应用程序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是必需的,否则错误会冒泡。
这是一个可能的解决方案吗?
您是否拥有B-method(即您可以更改它吗?)
我假设B-method在本质上是不可取消的,你只是取消了在模块A中调用它的后台工作器?
B-method需要更改为可取消或可重入。通过可重入,我的意思是它将允许对自身进行多次调用,并将重用任何已经在进行中的现有初始化序列。