【问题标题】:C# How to kill a blocked thread?C#如何杀死一个阻塞的线程?
【发布时间】:2018-02-21 00:20:34
【问题描述】:

我有一个线程:

void threadCode(object o)
{
  doStuffHere(o); // Blocking call. Sometimes hangs.
}

我这样称呼它:

Thread t = new Thread(new ThreadStart(delegate()
  {
    threadCode(o);
  }));
t.Start();

StopWatch sw = new StopWatch();
sw.Start();

while (t.IsAlive)
{
  Application.DoEvents();

  if (sw.EllapsedMilliseconds > myTimeout)
    // Somehow kill t even though doStuffHere(o) is blocked (but hung)
}

我正在使用.NET Zip Library 并调用ZipFile.CommitUpdate(),这在大多数情况下都有效,但有时只是挂起。我不知道为什么,我在文档中看不到任何说明为什么会发生这种情况的内容。一个不应该超过 5 - 10 秒的小文件有时会在那里放置超过 5 分钟而没有任何进展。进程资源管理器中的 I/O 图显示进程没有读取或写入,并且没有 CPU 使用率。基本上,如果发生这种情况,我想杀死CommitUpdate(),然后再试一次或两次,然后放弃。

知道如何杀死卡在阻塞调用中的线程吗?

(或者 - 那些对这个 zip 库有经验的人:你知道为什么它有时会与一些文件一起挂起吗?我正在修改 .docx 和 .pptx (GZip) 文件的内容。这将是一个理想的解决方案。)

【问题讨论】:

  • 杀死线程不是一个好主意,因为它不会释放资源。我建议使用一些维护的 .NET 组件,它没有此类错误并且您可以在哪里获得支持。
  • 另外,一般来说,不要开始自己的线程。 stackoverflow.com/questions/684640/…

标签: c# multithreading zip gzip block


【解决方案1】:

如果您要使用Thread.Abort() 终止挂起的线程,请确保在您的线程代码中处理ThreadAbortException。正常模式是:

try {
    // do work here
}
catch (ThreadAbortException) {
    // allows your thread to gracefully terminate
    Thread.ResetAbort();
}
catch {
    // regular exception handling
}

如果您不遵循上述模式,那么您的线程最多只能不正常地终止。在最坏的情况下,您可能会遇到许多其他问题。

【讨论】:

    【解决方案2】:

    你可以拨打Thread.Abort血腥谋杀线程。

    线程将无法自行清理(finally 块除外);取决于它当时正在做什么,它可能会严重破坏您的程序。

    【讨论】:

      【解决方案3】:

      不要使用 Thread.Abort() 来解决您正在使用的库中的错误。 (或者它可能是您的代码中的错误)。

      要么修复原始错误,要么移至其他库。

      ps:您可能想尝试使用 DotNetZip 来代替 SharpZipLib。

      【讨论】:

        【解决方案4】:

        除了使用秒表之外,您还可以这样做:

        Thread thread = new Thread(new ThreadStart(delegate()
        {
           threadCode(o);
        }));
        thread.Start();
        
        thread.Join(myTimeout);
        if(thread.IsAlive)
        {
           thread.Abort();
        }
        

        【讨论】:

        • 没想到这么简单。我现在要试试这个。我以为 Thread.Abort() 只是向线程发送了一个信号以中止,这将触发 Thread 中的事件处理程序。
        • @Ozzah:不;这是安全的方法。 Abort危险的
        • @SLaks 虽然MSDNCalling this method **usually** terminates the thread. 我想知道这意味着什么。
        • 如果线程在catchfinally中调用ResetAbort,它不会终止。
        【解决方案5】:

        使用 Thread.Abort() 方法杀死一个线程。详情请见http://msdn.microsoft.com/en-us/library/aa332365(VS.71).aspx

        【讨论】:

          【解决方案6】:

          作为最后的手段,您可以使用Thread.Abort() 来终止线程 - 不要期望任何有序的关闭。

          【讨论】:

            【解决方案7】:

            我自己没有这样做,所以我不确定,但是t.Abort(); 能做到吗?

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-06-27
              • 1970-01-01
              • 1970-01-01
              • 2011-06-29
              • 1970-01-01
              相关资源
              最近更新 更多