【问题标题】:InvokeRequired hangsInvokeRequired 挂起
【发布时间】:2011-04-28 11:15:35
【问题描述】:

UI 线程偶尔会在以下方法中的语句 'if (this.InvokeRequired)' 处挂起。

你能帮我找出问题的原因吗

  public void OnModuleInitializationCompleted(object sender, EventArgs e)
  {
    ModuleStatusWindow.Logger.LogMessage("OnModuleInitializationCompleted", LogMessageType.Information, "Received {0}", (sender as IModule).Name);
    if (this.InvokeRequired)
    {
      this.BeginInvoke(new ECEventsHandler(OnModuleInitializationCompleted), sender, e);
    }
    else
    {
      CheckIfAllModulesInitComplete();
    }
  }

  private void CheckIfAllModulesInitComplete()
  {
    ModuleStatusWindow.Logger.LogMessage("CheckIfAllModulesInitComplete", LogMessageType.Information, "Enter >>");
    this._moduleStatusGrid.DataSource = this._moduleDataList.ToArray();
    this._moduleStatusGrid.Invalidate();
    ModuleStatusWindow.Logger.LogMessage("CheckIfAllModulesInitComplete", LogMessageType.Information, "Updated grid control...");
    if (this._moduleDataList.Count(moduleData => !moduleData.IsInitOver) == 0)
    {
      this._footprint.DeActivate();
      ModuleStatusWindow.Logger.LogMessage("CheckIfAllModulesInitComplete", LogMessageType.Information, "Stopping message listenr...");
      ClientMessageListner.Stop();
      ModuleStatusWindow.Logger.LogMessage("CheckIfAllModulesInitComplete", LogMessageType.Information, "Closing Window...");
      this.Close();
    }
    ModuleStatusWindow.Logger.LogMessage("CheckIfAllModulesInitComplete", LogMessageType.Information, "Leave <<");
  }

【问题讨论】:

  • 你是如何确定它挂在那里的特别是
  • 从日志文件中,我可以看到这个 InvokeRequired 语句之前的日志条目。但是 CheckIfAllModulesInitComplete 中的日志条目不存在于日志文件中
  • 有没有可能实际上是对记录器的调用导致挂起?
  • @BugFinder:记录器模块相当稳定。我不认为挂在记录器中
  • 我不是说它不稳定,但可能是它导致了锁定,并且没有返回结果。只是一个想法。特别是如果它并不总是很容易追踪

标签: c# .net multithreading invokerequired


【解决方案1】:

我认为 InvokeRequired 不太可能挂起。 BeginInvoke 可能,但我认为不会。

一些想法。

BeginInvoke 运行正常,但 UI 线程很忙,因此它永远无法运行 OnModuleInitializationComplete。这个线程继续做什么?它是否开始等待(例如调用 EndInvoke)?

InvokeRequired 返回 false 并且您的 CheckIfAllModulesInitComplete 方法挂起。

我会在 OnModuleInitializationComplete 中添加更多日志记录,以显示 If 已采用的路径,然后使用新信息更新您的问题。
如果您还可以提供有关此方法的代码的更多详细信息,它可能会很有用,尤其是在等待此方法完成的任何地方。

【讨论】:

  • 我在第一篇文章中添加了 CheckIfAllModulesInitComplete 的源代码。方法中的第一个日志条目在日志文件中不可用
  • 注意! InvokeRequired 可能会挂起,因为它会锁定当前控件。请参阅以下网址中的lock(this) [链接] referencesource.microsoft.com/#System.Windows.Forms/winforms/…
  • 假设如果有另一个线程A,先持有资源B,然后调用InvokeRequired(需要锁this)。同时,你的主线程(UI线程可能持有锁this)需要资源B。它来了一个死锁...
【解决方案2】:

我会在 InvokeRequired 之后和 BeginInvoke 调用之前添加一条日志消息。

我怀疑是 BeginInvoke 阻塞,因为 UI 线程很忙,也许是因为它正在等待其他东西。

【讨论】:

    【解决方案3】:

    很可能,您遇到了某种导致死锁的竞争条件。或者,您的调试信息被弄乱了,而这并不是真正的阻塞线。

    【讨论】:

      猜你喜欢
      • 2012-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      • 2013-04-24
      • 1970-01-01
      相关资源
      最近更新 更多