【问题标题】:How to kill Thread in my C# application?如何在我的 C# 应用程序中杀死线程?
【发布时间】:2011-11-04 07:11:28
【问题描述】:

我想在按钮单击事件中杀死/销毁我的应用程序中的线程。

        private void stop_btn_Click(object sender, EventArgs e)
        {
            Thread.Sleep();
        }

此事件是否会挂起我的应用程序?

这是我的线程开始的代码

        DataTable myTable = new DataTable();`enter code here`
        myTable = msgDataSet.Tables["text"];
        DataRow[] myRow;
        myRow = myTable.Select();

        for (int x = 0; x < myRow.Count(); x++ )
        {
            SendKeys.SendWait(myRow[x]["msg"].ToString());
            SendKeys.SendWait("{Enter}");
            int sleep = int.Parse(textBox2.Text);
            Thread.Sleep(sleep);
        }
        Thread Spam1 = new Thread(new ThreadStart(Send1));
        Spam1.Start();

【问题讨论】:

  • Thread.Sleep 将活动的当前(您运行 stop_btn_Click 的)线程置于睡眠状态,因此应用程序挂起是正常的。
  • 你想杀死哪个线程?您的应用程序的主线程?
  • @lvar 所以请告诉我如何通过挂起我的应用程序来停止线程?
  • @invisible 是的,我想关闭我的应用程序的主线程。
  • 关闭应用程序的主线程(以及其他所有内容)而不保存/清理任何内容等。Process.GetCurrentProcess().Kill() 应该可以解决问题。

标签: c# multithreading


【解决方案1】:

请参阅这篇文章,了解为什么永远不要尝试致电 Thread.Abort

http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation

问题是您在该线程中破坏了异常安全性。这是因为Thread.Abort 将在该线程内的某个任意点抛出异常,这可能是在加载资源之后,但在线程进入支持干净卸载该资源的 try/catch 之前。

相反,您应该在该线程中运行的代码中构建合作取消。然后设置某种“取消请求”状态,并让线程自行终止。例如:

foreach(var value in aBunchOfData)
{
    if(isCancelled)
    {
        break;
    }

    // Continue processing here...
}

在这种情况下,您将公开isCancelled,并让您的父线程将其设置为true

如果你use a BackgroundWorker to implement your background thread,这个模式就很清楚了。

【讨论】:

  • 但我如何才能将我的线程名称访问到我的按钮事件?当我访问我的线程以中止或挂起这给我以下错误错误:当前上下文中不存在名称'Spam1'
  • @RizwanKhan:查看 BackgroundWorker。在主窗体中创建它的一个实例,并将后台工作人员作为成员变量保留在窗体中。 BackgroundWorker 为您提供可以从两个线程访问的共享取消状态。请参阅底部的链接,或 google backgroundworker。
【解决方案2】:

如果你想强制关闭一个线程,你可以调用Abort(),它会在目标线程上引发一个ThreadAbortedException

myThread.Abort()

目标线程有机会捕获它并在需要时清理任何资源(当然,如果它想通过捕获异常并继续前进,它也可以忽略它,但这是 IMO 不好的做法)

【讨论】:

  • @lsak-savo 但我如何才能将我的线程名称访问到我的按钮事件?当我访问我的线程以中止或挂起这给我以下错误错误:当前上下文中不存在名称'Spam1'
  • 你需要持有对它的引用。当你做 myThread = new Thread(...); 时你会得到 ref
【解决方案3】:

您编写的代码将使 UI 线程进入睡眠状态->您的应用程序将挂起。你如何实现线程?如果您使用的是BackgroundWorker-您可以enable thread cancellation,如果您使用的是Task-您可以提供cancel token to it。如果您使用的是 Thread- 您可以选择Abort() 方法。
PS..如果您想停止您的应用程序(主线程)-您可以:
关闭主窗口 ||调用应用程序退出 ||调用进程kill....

【讨论】:

  • Morgan-Graham 但是我如何才能将我的线程名称访问到我的按钮事件?当我访问我的线程以中止或挂起这给我以下错误错误:当前上下文中不存在名称'Spam1'
  • @Rizwan Khan,第一个问题:为什么你甚至想在上面的代码中中止线程?..如果你真的这样做-最好使用 Task(in c#4) 或 BackgroundWorker(>=c #2)。通过 UI 线程的存在,它们更容易控制。看看他们的样品。顺便说一句,请阅读albahari.com/threading。最好您自己理解问题,然后使用我们的答案。
猜你喜欢
  • 1970-01-01
  • 2011-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 2017-11-11
  • 2016-08-06
相关资源
最近更新 更多