即使我认为控件的窗口句柄已经创建,BeginInvoke 仍然声称它没有被创建。

3
在我的表单构造函数中,我调用了以下代码:

InitializeComponent(); // boilerplate placed by VS, initializing controls
label1.BeginInvoke(new InvokeDelegate(RefreshLabelDelegate));

但是,我收到了一条可怕的异常消息:

"在窗口句柄创建之前,无法在控件上调用Invoke或BeginInvoke"

据我所知,所有的线程都是相同的,为什么会出现这种异常呢?

4个回答

4
将构造函数中的 label1.BeginInvoke 移动到 Form_Load 事件处理程序中。

当结合了@HansPassant的解释时,这个简短而有趣的提示解决了我的问题。谢谢! - Not So Sharp

4
本机窗口句柄并不会在构造函数中创建。它要在稍后调用表单的Show()方法之后才会发生。这是典型的.NET懒惰方式。Load事件是在创建后运行的第一个标准事件。还有HandleCreated事件,但它可能会运行多次。
在这里实际上很少需要使用BeginInvoke,它是用来在创建Label1控件的线程上运行代码的。构造函数应该已经在该线程上运行了,如果没有,则非常不健康。如果想绘制标签,请改用Form的Shown事件,这是在表单实际可见给用户之后运行的第一个事件。

你确实解释得很清楚。谢谢。+1。 - Not So Sharp

2

0
不要调用BeginInvoke,没有理由。在控件的构造函数中,最好已经在适当的UI线程上了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接