gpt4 book ai didi

c# - 在 WinForms 中保持对控件的全局引用以访问 GUI 线程

转载 作者:太空宇宙 更新时间:2023-11-03 11:50:22 25 4
gpt4 key购买 nike

(这个问题有点历史,请多多包涵)

this问题,我谈到了集中更新 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();
}

上周,考虑到在处理事件时(在我的代码中)总是会发生这种情况,部分灵感来自 Dustin Campbell的事件扩展方法,我编造了这个:

//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 中有上下文的概念,但我不知道在 vanilla WinForms 中有什么等效的东西。我可以想象如果我尝试更新尚未处理的控件可能会出现问题(但在那种情况下我是 screwed anyway )。

最佳答案

这样做会限制您只能使用一个主窗体和一个 GUI 线程。但是对主 GUI 线程的需求是 .NET 表单(和底层 Win32 API)的一个要求,所以它不太可能改变。

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

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

关于c# - 在 WinForms 中保持对控件的全局引用以访问 GUI 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2264273/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com