【问题标题】:IsHandledCreated is set to false but during runtime it is set to true?IsHandledCreated 设置为 false 但在运行时设置为 true?
【发布时间】:2012-06-29 07:58:53
【问题描述】:

嗨,

我在 Application.Exit 期间运行了以下代码:

            if (InvokeRequired && this.IsHandleCreated)
            {
                this.Invoke(new Action(() => EndUpdate(Caller)));
                return;
            }

这会引发异常:在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke,但只能在应用程序正在运行时调用。

奇怪的是,当调试器因错误而中断时,我可以看到 InvokeRequired 和 IsHandledCreated 都设置为 false,所以我不确定它是如何访问内部代码(this.Invoke)的?

在这种情况下,我只想关闭应用程序,没有任何异常。

【问题讨论】:

  • 在 if 语句上放一个断点,看看出错前的值是什么。
  • @saj > 我从来没有听说过如果出错了,所以我假设当它检查 InvokeRequired 和 IsHandleCreated 时,它会得到 True/True,但是在运行 Invoke 之前另一个线程会更改它.也许我可以在 Invoke 方法中实现对 IsHandleCreated 的检查,但这可能会导致同样的问题。

标签: c# winforms multithreading


【解决方案1】:

以这种方式检查条件不是线程安全的。 首先,当线程在 if 运算符和调用 Invoke 之间切换时,您可以达到竞争条件。在其他情况下,我建议您在此处放置一些同步,但无法进入框架代码。

另外,Invoke 将查询放入 UI 消息队列,然后 UI 线程将其从队列中提取并执行。同时,Invoke 使用 Form.Handle 等待 UI 线程完成执行此查询。 因此,请确保您没有在 EndUpdate 方法中调用 Form.Close(),否则可能会在等待时导致异常。

我只是建议您将 EndUpdate() 调用放入 Form.OnClosing() 覆盖。那将是线程安全的,并且 Handle 保证存在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-11
    • 2021-04-14
    • 2023-02-09
    • 2015-11-27
    • 1970-01-01
    • 2020-06-23
    • 2014-11-05
    • 1970-01-01
    相关资源
    最近更新 更多