在 WinForms 中保留对控件的全局引用以访问 GUI 线程

2024-03-23

(这个问题有一点历史,请耐心听我说)

In this https://stackoverflow.com/questions/192980/boiler-plate-code-replacement-is-there-anything-bad-about-this-code问题,我谈到了集中更新 GUI 所需的“跨线程”骗局的可能性,如下所示:

//Utility to avoid boiler-plate InvokeRequired code
//Usage: SafeInvoker.Invoke(myCtrl, () => myCtrl.Enabled = false);
public static void Invoke(Control ctrl, Action cmd)
{
    if (ctrl.InvokeRequired)
        ctrl.BeginInvoke(new MethodInvoker(cmd));
    else
        cmd();
}

上周,仔细考虑了这样一个事实:在处理事件时,这种情况总是会发生(在我的代码中),部分灵感来自达斯汀·坎贝尔 http://diditwith.net/CommentView,guid,aacdb8ae-7baa-4423-a953-c18c1c7940ab.aspx的事件扩展方法,我编写了这个:

//Utility to avoid boiler-plate SafeInvoker.Invoke code
//Usage obj.EventRaised += obj_EventRaised.OnGUIThread(controlreference);
public static EventHandler OnGUIThread(this EventHandler h, Control ctrl)
{
    // lambda expressions are not syntactic sugar, they are syntactic crack!
    return (s, e) => SafeInvoker.Invoke(ctrl, () => h(s, e));
}

这里让我烦恼的是总是必须有一个控件在手。据我所知,只有一个 GUI 线程,因此任何控件都可以在这里执行。

我想知道如何创建一个“GUIContext”单例,并在应用程序启动时向它抛出对我的主窗体的引用,然后从我的扩展方法访问它,从而消除对 ctrl 参数的需要。

这是一个坏主意吗?如果是的话,为什么?有更好的方法吗?我知道在 Rx 中有一个 Context 的概念,但我不知道在 vanilla WinForms 中有什么等价的东西。我可以想象如果我尝试更新尚未处理的控件可能会出现问题(但在这种情况下我无论如何都搞砸了 https://stackoverflow.com/questions/246058/system-invalidoperationexception-the-object-is-currently-in-use-elsewhere-ho).


这样做会将您限制为单个主窗体和单个 GUI 线程。但是对主 GUI 线程的需求与 .NET 表单(以及底层 Win32 API)的需求一样,因此它不太可能改变。

您会知道您的应用程序的单一主表单是否可能会改变。即使确实如此,您的单例也将是一个更好的地方来跟踪哪个表单是“主”,而不是将其传递给所有后台线程。

总的来说,这对我来说是一个合理的设计。十多年来,我一直在非托管应用程序中使用全局变量来保存 hwndMain,并且从未后悔过。

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

在 WinForms 中保留对控件的全局引用以访问 GUI 线程 的相关文章

随机推荐

  • Gridview EditItemTemplate DropDownList 获取 SelectedValue

    在我的 Gridview 中 我有以下模板字段
  • JSONP 与 Jquery 1.9 和 Jersey 2.5.1

    我用谷歌搜索了很多 但没有找到适合我需求的东西 我发现了这些类似的线程here https stackoverflow com questions 5359224 parsererror after jquery ajax request
  • 从 setup.py 中检测 python 包安装路径

    安装后 我想对安装创建的一些配置和数据文件进行软链接 如何确定从包的 setup py 中安装的新包文件的位置 我最初对路径 usr local lib python2 7 dist packages 进行了硬编码 但当我尝试使用虚拟环境时
  • Windows 上带有 c 的 128 位整数?

    Windows 上有没有能够本地使用 128 位整数的 C 编译器 例如 您可以在 Linux 上使用 gcc 并使用 uint128 t 在 Windows 上还有其他机会吗 如果 128 位也能在 32 位计算机上运行那就太好了 D M
  • PHP 应用程序中是否可能有太多函数?

    PHP 应用程序是否可以拥有太多功能 执行大量PHP函数是否会占用内存和资源 我正在开发的 WordPress 主题有很多功能 当我完成时可能超过 100 个 我担心我可能有太多功能 即使许多功能会导致更多的内存消耗 我还是建议您使用它们
  • WebStorm 2018.1.4 + ESLint:TypeError:this.CliEngine 不是构造函数

    我的配置是这样的 WebStorm 2018 1 4 ESLint 6 4 节点12 8 npm 6 10 2 Windows 8 1 如何消除帖子标题中的错误 这是一个代码示例 import GET DAILY SUCCESS GET H
  • 如何在 Apache PDfBox 中设置页面缩放选项

    在我的应用程序中 我使用 Apache PDFBox 来渲染 PDF 文件并进行静默打印 PDFBox 可以很好地渲染 PFD 但我遇到了问题scaling来到图片上 这里我想在打印PDF之前设置页面缩放 在 acrobat reader
  • 如何在 Next.js 中从服务器获取 HOC 中的数据?

    我使用 Next js 创建了新应用程序9 3 1 在带有 SSR 的旧应用程序中 我可以使用getInitialProps函数在 HOC 组件中 而不是在页面中 因此我可以从 HOC 组件中的服务器和页面中获取数据 像这样https gi
  • woocommerce 获取属性值列表

    我在 WordPress 上使用 woocommerce 创建一个简单的商店网站 并为产品添加了几个属性 这些是 size and color 根据尺码 我有多种值 包括小号 中号和大号 与颜色相同 即 红色 蓝色 绿色 我想要做的是在下拉
  • 在 Sass 中编写一个以 1 以外的值递增的循环

    在 SASS 中 循环的写法如下 for i from 1 through 100 stuff 这将产生 1 2 3 4 一直到 100 如何让循环以两个单位为间隔进行 for i from 1 through 100 step 2 stu
  • JavaFX 8 WebEngine:如何在 java 中将 console.log() 从 javascript 获取到 System.out?

    我使用 JavaFX 和 JavaFX WebEngine 中的 javascript 引擎来开发应用程序 我想从 javascript 获得反馈以进行调试 WebEngine 内的控制台输出会发生什么情况 有什么方法可以访问它 或者重定向
  • 如何在android中比较已知时间和当前时间?

    我正在尝试使用开始时间和结束时间 并计算当前时间的百分比 在开始时间和结束时间之间 例如 如果现在时间为 12 00 startHour 11 00 End Hour 14 00 则应返回 33 四舍五入 因为已经过去了 33 的时间 我已
  • mvvmcross 可扩展列表视图

    我只是想知道 ExpandableListViews 的功能或类似于 ExpandableListViews 的功能是否潜伏在 Mvvmmcross 框架内 或者这种类型的控件不适用于多平台要求 该功能位于http deapsquatter
  • Clojure 开发:IDE 还是 REPL?

    我已经使用 Clojure 一段时间了 想要创建一些比玩具更大 更复杂的项目 过去几年我一直在使用 Java 并且已经习惯了 IDE 为我所做的事情 编译大量类 将它们打包在 jar 中 创建批处理文件供用户启动它们 当我查看 Clojur
  • 从节目/列表中抛出 404

    我像这样查询视图 db design myviewname view foo key 22ABC123 22 结果如下 total rows 3 offset 3 rows 都好 由于没有找到文档 我想从节目或列表中抛出 404 那可能吗
  • 无法使用 JavaScript Promise 读取未定义的属性“then”

    我明白乍一看这可能看起来像重复的 但我已经看到了所有告诉我要退货的答案 但这不起作用 这是我的功能 function removePastUsersFromArray pullAllUsersFromDB then function use
  • 在 C# 中处理非常大的整数

    有谁知道我可以在 C 中计算非常大的整数的方法 我正在尝试计算数字的阶乘 例如 5 5 4 3 2 1 120 对于小数字 这不是问题 但尝试计算 unsigned int 的最大值 4 294 967 295 的阶乘似乎是不可能的 我已经
  • 移动还是不移动右值引用限定方法?

    在以下 C 11 代码中 应首选哪种 return 语句构造 include
  • Ant 邮件任务 - 发送带附件的邮件时出现问题

    当我尝试使用 ant 邮件任务时 它在发送带有附件的邮件时似乎不起作用 我当前面临的问题是 它在电子邮件正文中发送附件内容 而不是作为附件 即使详细输出显示为 它也是通过附件发送的 由于最初它抱怨缺少 jars 我添加了 mail jar
  • 在 WinForms 中保留对控件的全局引用以访问 GUI 线程

    这个问题有一点历史 请耐心听我说 In this https stackoverflow com questions 192980 boiler plate code replacement is there anything bad ab