首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c# -如何强制关闭运行它自己线程的后台工作人员

c# -如何强制关闭运行它自己线程的后台工作人员
EN

Stack Overflow用户
提问于 2014-08-06 12:35:39
回答 2查看 476关注 0票数 3

我有wpf应用程序,让我们称之为A-appA-app使用后台工作人员运行异步B-method。这个B-method位于一个不同的项目中,它为B-method init部分创建了几个线程。

用户可以要求运行B-method,也可以要求取消运行并重新启动。问题是,如果它在init时间内被取消,运行B-method的后台工作人员就会被取消,但是线程不会取消。重新启动会创建更多的线程,这些线程不能与以前运行的线程同时工作,并且会导致一些错误。

线程方法主要是等待。

如何停止B-method并取消它创建的线程?

一个不同的AppDomain可以在任何方面有所帮助吗?(而不是关闭整个应用程序域?)如果是的话,该怎么办呢?有更好的办法吗?

详细信息:

  • B方法在一些设备上运行测试(可能很多)。该方法的缺点是连接到设备( i/o ),所以大部分时间都花在等待上(这就是我们决定让连接并行的原因),.tring从两个不同的线程连接到同一设备可能会造成问题。
EN

回答 2

Stack Overflow用户

发布于 2014-08-06 12:50:12

我建议您不要创建线程,而是使用TaskScheduler并使用并行任务库:

http://msdn.microsoft.com/en-us/library/dd997402%28v=vs.110%29.aspx

TaskScheduler本身就是处理线程的ThreadPool的包装器。它甚至可以做一些诸如WorkStealing、Task等方面的工作。

最好从这里开始: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。这很麻烦,但是没有完美的世界,所以把表单想象为应用程序A,ClassB是应用程序B:

代码语言:javascript
复制
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,否则错误会冒泡。

这是可能的解决办法吗?

票数 0
EN

Stack Overflow用户

发布于 2014-08-07 09:38:32

你拥有B方法(你能改变它吗?)

我假设B-方法在本质上是不可取消的,而您只是取消在模块A中调用它的后台工作人员吗?

B-方法需要更改为可取消,或重新进入.对于可重入者,我的意思是它将允许对自身进行多个调用,并将重用任何已经在进行中的现有init序列。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25160604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档