【问题标题】:Killing a Thread that is stuck waiting for an answer杀死一个等待答案的线程
【发布时间】:2012-06-15 17:54:21
【问题描述】:

我正在用 C# 编写一个程序,它与一个小型显示单元交互,该单元执行一大堆与此问题无关的事情。

我遇到的问题详细如下: 当用户选择将尝试将某些设置保存到设备的按钮时,它会使用确认协议来确保设置通过 (意思是——它发送设置然后等待来自设备的确认包。)

我所做的是在我的主应用程序中生成一个线程,该线程将成为我将要生成的线程的“父”线程,它将尝试保存到设备中。目前,它的工作方式如下:

  • 生成线程 1 -> 尝试保存。

  • 如果超时,通过 Thread.Interrupt() 中断线程 1(释放设备的数据锁)。这行不通。它加粗锁定,直到设备关闭或拔出,然后出错。 (然后它会生成一个新线程,现在发生了,但它永远不会工作,因为第一个线程仍然锁定数据)。

  • 如果没有超时,线程 1 的回调让父线程知道不再生成任何线程。

  • 最后,如果没有线程成功,则整体尝试失败。

我也尝试过只生成并关闭一个线程来执行此操作,这也表现出相同的行为,即在等待来自设备的确认时,它会永久挂起,直到设备关闭或拔下电源。

没有办法将等待设备发送带有布尔值的 ack 封装起来,该布尔值可以设置为停止线程,因为它永远不会离开等待调用。这是嵌入式软件,所以我无法修改等待功能。我只能修改嵌入式软件的C#接口。

【问题讨论】:

  • 您使用的是哪个版本的 .NET Framework?
  • 最后一点我不是很清楚。调用了一个函数等待ACK,但是该函数存在并运行在主机而不是嵌入式系统上,为什么不能修改呢?是不是它是一个闭源驱动程序?您还必须想知道为什么从未收到 ACK?

标签: c# embedded


【解决方案1】:

您似乎在说您的线程 1 永远等待 ACK。另一个线程检测到超时条件并尝试中断线程 1。我建议线程 1 不应该永远等待,而应该在等待 ACK 时自行超时。然后线程 1 可以重试或出错退出,不需要另一个线程的中断。

【讨论】:

  • 我不确定你的意思。如果线程忙于等待函数调用其运行完成,则线程不会超时。它被占用了。它必须在自身之外被打断,因为它被占用了。
  • 我认为@kkrambo 建议您修改线程1,以便它知道超时条件。这可能是通过执行诸如轮询结果之类的操作。如果不了解有关您的线程如何锁定的更多详细信息,则很难提出具体建议。
  • 你的线程调用的函数不应该永远运行。它应该超时并返回错误。我想象您正在为某个通信端口调用 Read() 函数。您应该能够在调用 Read() 时指定超时。或者,也许您可​​以在打开通信端口时指定超时。或者也许它不是一个通信端口,而是像轮询一个标志位这样简单的东西。在这种情况下,您不应该永远轮询标志。超时后放弃。
【解决方案2】:

您应该使用 Thread.Abort 而不是 Interrupt。 为了您的进一步澄清,请查看此线程 Abort Vs Interrupt

这应该可以解决您的问题。

【讨论】:

  • 你不能从另一个线程调用 abort 来结束一个单独的线程。好吧,你可以,但它只会中止调用它的线程(这将是主线程......)
  • 那么在这种情况下,您应该为异步线程实现超时模式。看看这个stackoverflow.com/questions/710070/…。这只是一个想法。我相信这方面的事情可能会对您有所帮助。
  • 不幸的是,这个线程试图为我获取数据(它响应一个布尔值)。该线程没有概述任何维护数据有效性的方法。如果我将布尔值设置为 volatile,则中止/挂起的线程似乎不会释放锁,但如果我让它保持非易失性,它就有可能损坏。
  • 我想向您推荐这些东西。您的线程正在等待获取一些数据。您是否正在尝试修改一些数据。我猜不会。这是我在这里理解的。当你调用线程时。将其设置为自己抛出一些超时异常,而不是尝试中断它。 stackoverflow.com/questions/1540444/… 。如果可能的话,你能在这里发布一些代码吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-27
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
  • 2022-11-29
相关资源
最近更新 更多