0

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

这是原始代码:

 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
    }

我试过的:

我通过将线程字段移出方法来尝试从按钮单击事件中的 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
 }

这就是我所做的,但我得到了错误:

在 e 和 genericlist 下:字段初始化不能引用非静态字段、方法或属性。

4

2 回答 2

13

如何使用 thread.abort()

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

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

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

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

此外:如果异步工作不受处理器限制,那么正确的解决方案是不使用工作线程。而是使用异步 IO 和await结果。您不会雇用工人站在您的邮箱旁,并告诉您何时收到信件;同样,不要雇佣工人站着等待 IO 任务完成。如果主线程不受 CPU 限制,则保持异步工作,并且您的线程将在等待时继续为用户请求提供服务。

我有一个错误a field initializer can not reference a non static field, method or property.

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

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

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

我的项目快结束了,因此我不想做很多改变。

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

我有最后期限

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

于 2019-12-19T18:49:24.850 回答
-1

如果你必须使用线程,试试这个。否则,请尝试以下链接中的 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;
        }
于 2019-12-23T14:10:52.200 回答