如何使用 thread.abort()

How to use thread.abort()

如果用户需要,我只是尝试通过单击按钮停止进程来中止线程,而不是退出应用程序。

这是原始代码:

 private void Abort_Click(object sender, EventArgs e)
    {
     //   thread1.Abort();
    }

    ///  Runs method 'Copy' in a new thread with passed arguments - on this way we separate it from UI thread otherwise it would freeze
    private void backgroundCopy_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e )
    {

        List<object> genericlist = e.Argument as List<object>;
        Thread thread1 = new Thread(() => Copy(genericlist[0].ToString(), genericlist[1].ToString()));
        thread1.Start();
        thread1.Join(); //Waiting for thread to finish
    }

我尝试过的:

我尝试通过将 thread 字段移出方法来从按钮单击事件中获取 Abort() 线程,这样您就可以从按钮单击事件中获取访问权限,但它会抛出许多错误:

 object sender;
 System.ComponentModel.DoWorkEventArgs e;
 List<object> genericlist = e.Argument as List<object>;
 Thread thread1 = new Thread(() => Copy(genericlist[0].ToString(), genericlist[1].ToString()));



 private void Abort_Click(object sender, EventArgs e)
 {
     thread1.Abort();
 }

 ///  Runs method 'Copy' in a new thread with passed arguments - on this way we separate it from UI 
  thread otherwise it would freeze
 private void backgroundCopy_DoWork( )
 {


     thread1.Start();
     thread1.Join(); //Waiting for thread to finish
 }

我就是这样做的,但出现错误:

under e and genericlist : a field initialize can not reference a non static field, method or property.

How to use thread.abort()

使用Thread.Abort()曾经,除非您正在紧急关闭整个应用程序域或过程。你永远不要这样做。我希望这很清楚。

您从不这样做的几个原因是:

  1. 有许多比中止异步工作流更好的控制异步工作流取消的方法。
  2. 中止线程并不能保证真正中止该线程。主动抵抗被中止的线程有办法无限期地延迟中止。它不可靠,所以不要使用它。
  3. 最重要的是:中止线程可以保证维护 CLR 用来管理线程的内部机制的正确性保证保持程序的正确性!线程中止可能会导致您的程序不变量以有趣的方式被违反,这经常导致崩溃。 (练习:列出在构造带有终结器的对象期间发生线程中止的可能后果)

构建程序的正确方法是使用协作取消模式,并将异步工作表示为可以取消的任务。异步工作然后定期轮询令牌以查看它是否需要取消自身。

此外:如果异步工作不受处理器限制,那么正确的解决方案是不使用工作线程。相反,使用异步 IO 和 await 结果。你不会雇一个工人站在你的邮箱旁边,告诉你信件什么时候到达;同样,不要雇用工人站在那里等待 IO 任务完成。如果主线程未绑定 CPU,则将异步工作保留在主线程上,您的线程将在等待期间继续为用户请求提供服务。

I got an error a field initializer can not reference a non static field, method or property.

没错。字段初始值设定项不能以 任何 方式使用 this,包括在 lambda 体内的隐式使用。这样做的原因是因为 字段初始化程序在构造函数主体运行之前运行 ,但它是构造函数的主体初始化 this 的字段。语言设计试图避免您在这里写下讨厌的错误。

您需要将初始化逻辑移动到构造函数中。

但更一般地说,如果您的程序要求您必须异步执行可由用户取消的高延迟 IO 绑定任务,那么您选择了错误的机制来正确和安全地实现该目标。

I am near the end of the project therefor I don't want to make a lot of changes.

我相信你不会。越早开始解决架构问题,您就会越早获得正确、安全的实施。

I have a deadline

这是管理问题,不是技术问题。我的建议是你向你的管理层解释情况。他们应该知道,选择是使用结构不正确且可能不稳定的程序来满足截止日期,或者延长截止日期并将程序重组为符合用户要求的有原则的、正确的、安全的程序。管理层应该有权就他们付钱给你的项目的状态做出明智的决定。

如果你必须使用线程,试试这个。否则,像 link 中那样尝试 cancelAsync: https://www.wpf-tutorial.com/misc/cancelling-the-backgroundworker/

     // We will set this true to notify the worker threads return.
            private bool shouldAbort;
    // when hitting submit set:
    shouldAbort = false;
    void MethodThatDoesWork()
        {
                //we should stop if required
                if (shouldAbort)
                {
                    state.Stop();
                }
            //code
        }

我们必须确保在关闭表单时所有线程都已终止。 所以我们添加这些控件。

   private void ItemsCopyer_FormClosing(object sender, FormClosingEventArgs e)
       {
         System.Diagnostics.Process.GetCurrentProcess().Kill();
        }

        private void btnAbort_Click(object sender, EventArgs e)
        {
            shouldAbort = true;
            btnAbort.Enabled = false;
        }