在WinForms中保留对控件的全局引用以访问GUI线程 [英] Keeping a global reference to a control in WinForms for accessing GUI thread

查看:80
本文介绍了在WinForms中保留对控件的全局引用以访问GUI线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(这个问题有一点点历史,请忍受)

这个问题中,我谈到了集中更新更新GUI所需的跨线程"轨迹的可能性,如下所示:

In this question, I talked about the possibility of centralising the 'cross thread' hocus-pocus that is required for updating the GUI like so:

//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();
}

上周,考虑到在处理事件时总是会发生这种情况(在我的代码中),并且部分受

Last week, mulling over the fact that this always happens (in my code) when handling an event, and partly inspired by Dustin Campbell's event extension method, I cooked up this:

//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线程,因此任何控件都可以在这里进行.

The thing that bugs me here is always having to have a control to hand. As far as I know, there is only one GUI thread, so any control would do here.

我想知道是否要创建一个'GUIContext'单例,并在应用程序启动时将其扔给我的主窗体引用,然后从我的扩展方法中访问它,从而消除了对ctrl参数的需要.

I got to wondering about creating a 'GUIContext' singleton and throwing it a reference to my main form when the application starts up, then accessing that from my extension method, thus removing the need for the ctrl parameter.

这是个坏主意吗?如果是,为什么?有更好的方法吗?我知道在Rx中有上下文的概念,但是我不知道任何与香草WinForms等效的东西.我可以想象如果我尝试更新尚未处理的控件可能会出现问题(但在那种情况下,我

Is this a bad idea, and if so, why? Is there a better way to do it? I know that in Rx there is a notion of Context, but I'm not aware of anything equivalent in vanilla WinForms. I can imagine there might be a problem if I try to update a control that is not yet handled (but in that case I'm screwed anyway).

推荐答案

执行此操作会将您限制在一个主窗体和一个GUI线程中.但是,除了任何其他内容外,.NET表单(和基础Win32 API)也都需要主要的GUI线程,因此它不太可能改变.

Doing this would restrict you to a single main form and a single GUI thread. But the need for a main GUI thread is as much a requirement of .NET forms (and the underlying Win32 API) as anything, so it's not very likely to change.

您会知道应用的单一主表单是否可能会更改.即使这样做,与将表单传递给所有后台线程相比,单例还是更好的跟踪哪个表单是主表单"的地方.

You would know if having A single main form for your app is likely to change or not. Even if it it did, your singleton would be a better place to keep track of which form was "main" than to pass that around to all of the background threads.

总的来说,这对我来说似乎是一个合理的设计.我使用全局变量将hwndMain保留在非托管应用程序中已有十多年了,从不后悔.

On the whole, this looks like a reasonable design to me. I've used a global variable to hold hwndMain in my unmanaged apps for more than a decade and never regretted it.

这篇关于在WinForms中保留对控件的全局引用以访问GUI线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆