如何强制关闭运行自己线程的后台工作线程

本文关键字:线程 后台 工作 自己 运行 何强制 | 更新日期: 2023-09-27 18:16:43

我有一个wpf应用程序,我们叫它A-appA-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.aspx

TaskScheduler本身是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需要更改为可取消或可重入。通过可重入,我的意思是它将允许对自身进行多次调用,并将重用任何已经在进行中的现有初始化序列。