ThreadSafe表单隐藏/显示 [英] ThreadSafe form hide/show

查看:81
本文介绍了ThreadSafe表单隐藏/显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将数据从系统托盘中带有图标的最小化表单传输到同一应用程序中的目标表单.这是通过使用委托来实现的.现在,我想在scource空闲时隐藏目标表单,在计划发送数据但目标挂起Form.Hide/Show调用时隐藏Show().请任何人对如何实现此目标有任何想法.

I need to transfer data from a form minimised with an icon in the system tray to a target form in the same appication. This has been achieved by the use of delegates. Now I would like to Hide() the target form when the scource is idle and Show() when data is scheduled for sending but the target hangs on the Form.Hide/Show call. Has anyone any ideas how to achieve this please.

推荐答案

问题尚不清楚,并且充满了不相关的信息,而一些相关的信息则可能丢失了.基本上,对任何UI方法/属性的所有调用都应仅从UI线程完成.

因此,如果您想使任何线程安全地显示或隐藏表单,则应执行以下操作:
The question is not clear and full of unrelated information while some related information is probably missing. Basically, all the calls to any UI methods/properties should be done only from the UI thread.

So, if you want to cause showing or hiding the form safely from any thread, you should do this:
static void ShowHideForm(Form form, bool show /* otherwise hide */) {
    if (form.InvokeRequired) {
        form.Invoke(new Action<Form, bool>((formInstance, isShow) => {
            if (isShow)
                formInstance.Show();
            else
                formInstance.Hide();
        }), form, show);
    } else {
        if (show)
            form.Show();
        else
            form.Hide();
    } //if
} //ShowHideForm



您可以使用非中断BeginInvoke来代替Invoke,后者等待UI线程事件周期中的委托处理,当代理实例及其调用的参数发布到UI线程的队列中时,它将立即返回,请参阅下面的参考资料.

确实不需要InvokeRequired的检查:如果仅使用调用方法(在这种情况下为第一个分支),则此代码将起作用.从UI线程调用时,非调用分支(直接调用)将更加有效.在另一种情况下,仅需要一个调用部分:当您确定仅从非UI线程调用上述代码时.同样,它可以在任何线程上工作,但如果从(相同)UI线程调用,效果会更差.

您无法从非UI线程调用与UI相关的任何操作.相反,您需要使用System.Windows.Threading.DispatcherInvokeBeginInvoke方法(对于Forms或WPF)或System.Windows.Forms.Control(仅对于Forms).

在我过去的答案中,您将找到有关其工作原理的详细说明和代码示例:
Control.Invoke()与Control.BeginInvoke() [ ^ ],
Treeview Scanner和MD5的问题 [如何获取keydown事件在vb.net中的不同线程上操作 [启用禁用+多线程后控件事件不会触发 [ ^ ].

—SA



Instead of Invoke which waits for processing of the delegate in the UI thread event cycle, you can use non-bloking BeginInvoke which will return immediately when a delegate instance and parameters for its call are posted to the queue of the UI thread, see my references below.

The check of InvokeRequired is not really required: this code will work if only the invocation method is used (first branch under this condition). Non-invocation branch (direct call) will be just more effective when called from UI thread. There is another case when only an invocation part is needed: when you are sure that the code above will be called only from a non-UI thread. Again, it will work from any thread, but it would be less effective if called from (the same) UI thread.

You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA


我将代码修改为

I modfied code to

Delegate Sub ShowHideForm_Delegate(ByVal pform As Form, _
                                   ByVal pshow As Boolean)

Private Sub ShowHideForm_ThreadSafe(ByVal pform As Form, _
                                    ByVal pshow As Boolean)
If pform.InvokeRequired Then
     Dim MyDelegate As New ShowHideForm_Delegate(AddressOf ShowHideForm_ThreadSafe)
        pform.Invoke(MyDelegate, New Object() {[pform], [pshow]})
    Else
        If (pshow) Then
            pform.Show()
        Else
            pform.Hide()
        End If
    End If
End Sub



尽管目标上的Mouse Click事件存在问题,但此方法正常工作
表格(pform)

再次感谢)



This works fine although there is an issue with Mouse Click event on target
form(pform)

Thanks again)


这篇关于ThreadSafe表单隐藏/显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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