表==虚假载控制InvokeRequired和InvokeRequired ==真 [英] InvokeRequired of Form == false and InvokeRequired of contained control == true

查看:439
本文介绍了表==虚假载控制InvokeRequired和InvokeRequired ==真的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

怎么可能?我有Windows窗体控件,来源于System.Windows.Forms.Form中包含在这种形式的WebBrowser控件。 WebBrowser对象实例的形式构造函数中创建(在InitializeComponent()方法)。然后在后台线程我操作与web浏览器的内容,而且我发现,在某些情况下,Form.InvokeRequired ==假的,而WebBrowser.InvokeRequired ==真。这怎么可能?

how is it possible? I have windows Form control, derived from System.Windows.Forms.Form with WebBrowser control contained in this form. Webbrowser object instance is created in constructor of form (in InitializeComponent() method). Then in background thread I manipulate with content of WebBrowser, and I found that in some cases Form.InvokeRequired == false, while WebBrowser.InvokeRequired == true. How can it be?

推荐答案

Form.InvokeRequired 返回前显示形式。

我做了一个简单的测试:

I did a simple test:

Form2 f2 = new Form2();
Thread t = new Thread(new ThreadStart(() => PrintInvokeRequired(f2)));
t.Start();
t.Join();

f2.Show();

t = new Thread(new ThreadStart(() => PrintInvokeRequired(f2)));
t.Start();
t.Join();

与助手

private void PrintInvokeRequired(Form form)
{
    Console.WriteLine("IsHandleCreated: " + form.IsHandleCreated + ", InvokeRequired: " + form.InvokeRequired);
}

输出

IsHandleCreated:假,InvokeRequired:假
  IsHandleCreated:的确,InvokeRequired:真

IsHandleCreated: False, InvokeRequired: False
IsHandleCreated: True, InvokeRequired: True

另外请注意,这在一定程度上记录MSDN

Also note that this is somewhat documented on MSDN:

如果该控件的句柄尚不   存在,InvokeRequired搜索了   控件的父链,直到找到   控制或形式,确实有   窗口句柄。如果没有合适的   手柄可以发现,在   InvokeRequired方法返回false。

If the control's handle does not yet exist, InvokeRequired searches up the control's parent chain until it finds a control or form that does have a window handle. If no appropriate handle can be found, the InvokeRequired method returns false.

这意味着,InvokeRequired可以   如果不需要调用返回假   (呼叫发生在同一线程),   或者,如果对照上创建   不同的线程,但控制的   手柄还没有被创建。

This means that InvokeRequired can return false if Invoke is not required (the call occurs on the same thread), or if the control was created on a different thread but the control's handle has not yet been created.

在情况下,控件的句柄   尚未创建,你应该   不能简单地调用属性,方法   或控制的事件。这可能   导致控件的句柄是   在后台线程创建的,   隔离控制在一个线程   未经消息泵和使   应用程序不稳定​​。

In the case where the control's handle has not yet been created, you should not simply call properties, methods, or events on the control. This might cause the control's handle to be created on the background thread, isolating the control on a thread without a message pump and making the application unstable.

您可以防止这种情况下,通过   还检查的价值   InvokeRequired时IsHandleCreated   返回false在后台线程。   如果控制手柄还没有得到   创建的,则必须等到它有   调用调用或之前创建   BeginInvoke的。通常情况下,这种情况   仅当创建一个后台线程   在主窗体的构造函数   为应用程序(如在   Application.Run(新的MainForm()),   形式已被证明之前或   Application.Run被调用。

You can protect against this case by also checking the value of IsHandleCreated when InvokeRequired returns false on a background thread. If the control handle has not yet been created, you must wait until it has been created before calling Invoke or BeginInvoke. Typically, this happens only if a background thread is created in the constructor of the primary form for the application (as in Application.Run(new MainForm()), before the form has been shown or Application.Run has been called.

您的解决方案是同时检查 IsHandleCreated

Your solution is to also check for IsHandleCreated.

编辑:
处理可在任何时间内WebBrowser控件或外部产生。这不会自动创建父窗体的句柄。


The Handle can be created at any time internal in the WebBrowser control or externally. This does not automatically create the handle of the parent form.

我创建了一个例子:

public Form2()
{
    InitializeComponent();

    Button button1 = new Button();
    this.Controls.Add(button1);

    Console.WriteLine("button1: " + button1.IsHandleCreated + " this: " + this.IsHandleCreated);
    var tmp = button1.Handle; // Forces the Handle to be created.
    Console.WriteLine("button1: " + button1.IsHandleCreated + " this: " + this.IsHandleCreated);
}

与输出:

按钮1:假的:假
  按钮1:真这样的:假

button1: False this: False
button1: True this: False

这篇关于表==虚假载控制InvokeRequired和InvokeRequired ==真的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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