【问题标题】:Control.Invoke() stucksControl.Invoke() 卡住
【发布时间】:2013-02-26 09:17:05
【问题描述】:

我知道关于这个主题有几个主题,但我认为我的主题不同。 在我的应用程序中,我打开了一个表单,用户可以在其中输入一些参数以进行即将到来的打印。此打印应该在后台工作人员中运行。所以我用事件“OnFormClosing”解雇了那个后台工作人员。

在后台工作人员中,我需要访问 GUI 并更改/读取它,所以我需要一个 control.Invoke()。 “有时” Invoke 一直停留在调用调用本身并且不执行委托。我的主线程工作正常,没有被阻塞。我仍然可以与 GUI 交互做其他事情。在发布任何代码之前:除了

之外,是否还有其他条件可以执行 control.Invoke()
  • 主 GUI 线程未被阻塞
  • contorl 必须存在,句柄已创建且不被释放

主线程不需要是空闲的,并且调用调用正确吗?一旦主线程空闲,它应该继续......

感谢您的帮助

更新:

这是该问题期间的线程情况: 主线程正在执行这个:

Application.Run(appContext);

所以它是空闲的。 工作线程在这一行等待:

fileName = (string)cbPrintFile.Invoke(new Func<String>(() => cbPrintFile.Text));

不像我上面所说的那样执行。 cbPrintFile 是一个组合框

【问题讨论】:

  • 您应该使用ReportProgress 事件处理程序等向 UI 线程报告。见stackoverflow.com/questions/3289920/…
  • 您说您正在打开一个表单,然后在 OnFormClosing 方法上解雇您的后台工作人员。然后使用control.Invoke() 更新哪些控件?如果您尝试更新尝试关闭的表单,这可能是您的问题的一部分...
  • +1 只是为了与“Control.Invoke() 很烂”的标题相似。
  • @DanPuzey 不,因为没有后台工作人员它可以工作
  • @Killercam 我不想向 UI 报告任何进度,只是读取并设置一些 GUI 字段

标签: c# multithreading backgroundworker invoke


【解决方案1】:

Invoke 是“排队等待处理”。如果它变得“卡住”,则表明您已经死锁,例如因为 UI 线程仍在等待工作人员的事件处理程序中。如果代码解耦得当,你大概可以把Invoke换成BeginInvoke,这样可以让worker在排队工作后继续工作。当然,确保 UI 永远不会等待工作人员也是一件好事。如果试图在两个地方都持有lock(在同一个对象上),这可能会意外完成。您可以通过暂停应用程序、按 ctrl+dt 调出线程和 ctrl来进行调查>+d,c依次查看每个的调用栈。

【讨论】:

  • "如果代码解耦得当,你大概可以用 BeginInvoke 代替 Invoke",解耦在这里有什么帮助,请清除我的疑惑。
  • 我更新了我的帖子以显示实际情况。我同意,如果主线程很忙,这将阻止它,但事实并非如此。 “BeginInvoke”不会解决这个问题吧?因为它也会留在那里,并且“永远不会”像现在这样被执行。另外,如果我需要从 GUI 读取的值,它不会被返回。
猜你喜欢
  • 1970-01-01
  • 2017-12-29
  • 2011-08-04
  • 2011-11-17
  • 2014-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多