Control.Invoke 在隐藏的 ShowDialog 中“卡住”

2024-05-06

(我有解决这个问题的方法,但这不是我第一次被咬,所以我试图确切地了解发生了什么。)

  • 从我的申请中,我ShowDialog表单。
  • 表单上有一个按钮,单击该按钮时会调用另一个(非 GUI)线程上的代码。
  • 非 GUI 线程发回状态 (Pushed then Released) 通过 Control.Invoke
  • 当表格看到Pushed,它调用form.Hide()
  • 当表格看到Released,它会更改按钮的外观。

发生的情况是,有时(但并非每次)非 Gui 线程在尝试发送Released。无一例外,Gui 继续“工作”,但无论在哪个方向,都不可能与非 Gui 线程进行进一步的通信。

线程的(简化的)调用堆栈如下所示:

System.Threading.WaitHandle.WaitOne()
(...)
System.Windows.Forms.Control.WaitForWaitHandle()
(...)
System.Windows.Forms.Control.Invoke()
(...)
GuiCode.OnStatusChanged()
(...)
NonGuiCode.SetStatus()

如果我更换,问题就会消失ShowDialog with Show,但是 - 有趣的是 - 它会变得更好(发生得更少),但如果我注释掉执行以下操作的代码,它不会完全消失Hide on Pushed.

Update

谢谢nobugz https://stackoverflow.com/questions/2055960/control-invoke-getting-stuck-in-hidden-showdialog/2056427#2056427,我发现了死锁(我以前只在数据库中遇到过)!显然,用 Control.BeginInvoke 替换 Control.Invoke 可以解决此问题(状态事件有时仍然“卡住”,但它不会阻止所有后续通信)。


为了处理Control.Invoke()调用时,GUI 线程必须发送 Windows 消息,但是ShowDialog()是一个阻塞调用,所以它不能这样做,直到ShowDialog()返回。

Control.Invoke()也是阻塞的,调用它的线程必须等待,直到 GUI 线程拾取消息并处理它才能继续。如果代码包含Control.Invoke()是什么使得对话框消失,然后bingo,这就是你的僵局。

这有点棘手,因为像 SosEx 这样的死锁检测器dlk命令无法从转储或 WinDgb 会话中检测到问题 - GUI 线程处理中涉及的“锁”Control.Invoke()是“隐含的”,而不是实际的WaitHandle.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Control.Invoke 在隐藏的 ShowDialog 中“卡住” 的相关文章

随机推荐

  • python 中打印变量和字符串

    好吧 我知道如何打印变量和字符串 但是我如何打印类似 我的字符串 card price 的内容 它是我的变量 我的意思是 这是我的代码 print I have and here I would like to print my varia
  • 如何在 Dart 中打印美元符号 $

    我实际上需要在 Dart 中在变量之前打印一个美元符号 例如 void main int dollars 42 print I have dollars I have 42 我希望输出为 我有 42 美元 我怎样才能做到这一点 谢谢 飞镖弦
  • Java:删除链表中的所有元素

    Java中如何删除链表中的所有元素without使用已经可用的clear 方法 这项练习的灵感来自于电话采访中收到的一个问题 说我可以用 C 来做这个 void DeleteAllElement ListElement head ListE
  • 用于分享帖子的 Yammers REST API

    我想使用 REST API 从我的业务应用程序共享帖子 不是发布新消息 而是共享现有帖子 有谁知道要使用哪个端点以及如何实现它 当您使用 Yammer API 创建新帖子时 请将参数 shared message id 与要共享的消息的 m
  • 为什么 justify-content 不以我的 div 为中心?

    我试图将两个 div 水平居中放在爸爸 div 内 爸爸 div 设置为flex direction column因为我希望子 div 一个在另一个之下 但位于页面的中心 justify content center 应该做但不起作用 我终
  • 如何注释 .tsx 文件中的属性?

    给出以下 JSX 代码 div div 我怎样才能注释掉className my class className my class 不起作用 className my class 不起作用 TS1005 expected className
  • 如何在Azure数据工厂中传递不记名令牌API

    我有一个 API 它具有授权和不记名令牌 我在邮递员中进行了测试 它正在工作 但是 当我在 ADF 中使用 Web 活动时 它不起作用 我在 URL 部分传递 url 创建新标头 输入授权并指定值 Bearer token 出现以下错误 E
  • 有没有办法找到哪些 .NET 类实现了某个接口?

    例如 如果我想查看我的 NET 选项用于实现 IList 或 IDictionary 有没有办法找到它 例如在 MSDN 文档中 我认为可以使用反射器 http www red gate com products reflector
  • 玩笑测试因 refs 和 Form 失败

    我有一个搜索栏组件 如下所示 render const onChangeTextInput this props return
  • 如何在 TargetFrameworks 标记中每个框架运行一次的目标之前创建仅运行一次而不是一次的 MSBuild 目标?

    我有一个我部分拥有的代码生成器工具 现在 csproj 文件可以在其中列出多个目标框架并构建所有这些框架 我试图弄清楚如何使 MSBuild 目标仅在每个目标中生成一次代码无论列出了多少个目标框架 都将运行构建 并让每个目标框架的编译等待代
  • web请求超时处理?

    HttpWebRequest request HttpWebRequest WebRequest Create url request Timeout 20000 using WebResponse response request Get
  • Gradle 环境变量。从文件加载

    我是 Gradle 新手 目前我有这个任务 task fooTask doLast exec environment FOO KEY 1234567 Load from file here commandLine fooScript sh
  • 使用 WGET 运行 cronjob PHP

    我尝试执行一个 cron 并每 5 分钟运行一个 url 我尝试使用 WGET 但我不想下载服务器上的文件 我只想运行它 这是我使用的 crontab 5 wget http www example com cronit php 除了 wg
  • Material UI 自动完成弹出窗口自定义在单击时关闭

    我正在尝试通过覆盖来向 Material UI 自动完成纸张添加一个按钮PaperComponentprop并在论文的按钮处添加了一个按钮 但是点击该按钮会自动关闭自动完成搜索结果 如何防止自动完成搜索结果 Paper 在单击时关闭 这是一
  • 为什么要在注释中声明 PHP 变量类型?

    我对 PHP 还很陌生 我刚刚开始使用 NetBeans 来开发我的 PHP 代码 出乎意料的是 当我在查询中输入变量时 会弹出一个对话框 要求我完成注释以保存变量类型 我做了一些调查 发现这似乎是 NetBeans 的一个流行功能 但我找
  • 快速 shell 命令删除文本文件中的停用词

    我有一个 2GB 的文本文件 我正在尝试从此文件中删除经常出现的英语停用词 我有 stopwords txt 包含这样的 a an the for and I 使用 shell 命令 例如 tr sed 或 awk 执行此操作的快速方法是什
  • 可重复的随机数系列

    如何在 PHP 中获得一系列可重复的伪随机数 在旧版本的 PHP 中 我只需在RNG http en wikipedia org wiki Random number generation 但它不再起作用了 因为 PHP 改变了 rand
  • R中几个big.matrix对象的逐元素平均值

    我有 17 个文件支持的 big matrix 对象 暗淡 10985 x 52598 每个 4 3GB 我想计算其中的元素平均值 结果可以存储在另一个big matrix gcm res outputM 中 biganalytics ap
  • 如何使用可变参数模板声明 std::tuple?

    也许我在这里很天真 但我相信以下代码应该编译 template
  • Control.Invoke 在隐藏的 ShowDialog 中“卡住”

    我有解决这个问题的方法 但这不是我第一次被咬 所以我试图确切地了解发生了什么 从我的申请中 我ShowDialog表单 表单上有一个按钮 单击该按钮时会调用另一个 非 GUI 线程上的代码 非 GUI 线程发回状态 Pushed then