c# - 如何强制关闭运行它自己的线程的后台 worker

标签 c# multithreading asynchronous appdomain

我有一个 wpf 应用程序,我们称它为 A-appA-app 使用后台 worker 运行异步 B-methodB-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/

相关文章:

c# - 使用 base.Any(..) 警告是 : 'HashSet' does not contain a definition for 'Any'

c# - 从类库项目启动 WPF 窗口

java - 更新 Java 线程池中的 UI

JavaScript异步: Log the response from each action in the order it was called

c# - 一个字符的不同 ASCII 值

python - 如何停止守护线程?

c# - 系统.安全.HostProtectionException : Attempted to perform an operation that was forbidden by the CLR host

c++ - 使用重叠结构进行回调?

javascript - Console.logging 一个对象显示该对象包含一个尚未分配的属性

c# - Graphics.DrawPath 和 LinearGradientBrush 问题