尝试使用多线程添加控件时出错 [英] Getting an Error when trying to add a Control with Multithreading

查看:114
本文介绍了尝试使用多线程添加控件时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试做什么。

我正在尝试将一个按钮添加到一个分组框中,使用多线程,但它给了我一个错误。

错误:

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

错误图片

http://i.imgur.com/FP5kKe4.png



The Code 我写了,但给了我一个错误,任何帮助表示赞赏。

What i'm trying to do.
I'm Trying to add a Button to a Group box, with multi-threading but it gives me an error.
Error:
"Invoke or BeginInvoke cannot be called on a control until the window handle has been created."
Picture of the Error
http://i.imgur.com/FP5kKe4.png

The Code i wrote, but gives me an error, any help is appreciated.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim nt As New Thread(AddressOf BeforeAdding)
        nt.Start()
    End Sub
    Public Shared Function BeforeAdding()
        Dim rnd As New Random
        Dim str As String = rnd.Next(100, 10000)
        Dim btn As New Button
        AddControl(btn, str)
    End Function
    Public Shared Function AddControl(ctrl As Button, title As String)
            ctrl.Invoke(New MethodInvoker(Sub()
                                              ctrl.Dock = DockStyle.Left
                                              ctrl.Text = title
                                              Form1.GroupBox1.Controls.Add(ctrl)
                                          End Sub))
    End Function

推荐答案

这与多线程本身无关,它与UI调用机制有关。在 System.Windows.Forms 库中,它基于Windows消息队列。当然,只有当此控件已有窗口句柄时,才可以将任何内容放入某个窗口控件的队列中。在您的代码中,实例 ctrl 只是通过其构造函数创建的。当然,它没有窗把手。看看你在做什么:你在控制距离上调用 ctrl.Invoke ,这甚至都不是用户界面的一部分。



所以,你试图过早地使用 Control.Invoke :-)。



分辨率:使用 Form1.Invoke 替换 ctrl.Invoke 。对于调用添加哪个控件绝对不重要,它是已经参与要调用方法的线程的UI的任何控件。



And请不要使用 Form1 等名称以及任何其他自动生成的名称。此类名称违反了Microsoft命名约定。总是使用一些语义上有意义的名称重命名这样的对象。



背景

请查看我过去的答案话题:

Treeview扫描仪和MD5的问题 [ ^ ],

Control.Invoke ()与Control.BeginInvoke() [ ^ ]。



-SA
This is not related to multithreading itself, it is related to UI invocation mechanism. In the System.Windows.Forms library, it is based on Windows message queue. Naturally, you can put anything to a queue of some windowed control only if this control already has a window handle. In your code, the instance ctrl is just created through its constructor. Naturally, it has no a window handle. Look at what you are doing: you are calling ctrl.Invoke on a control distance which is not even a part of the UI yet.

So, you are trying to use Control.Invoke well too early :-).

Resolution: replace ctrl.Invoke with Form1.Invoke. It is absolutely not important which control is added for invocation, it is any control which already participates in the UI of the thread you want to invoke the method to.

And please never use names like Form1 as well as any other auto-generated names. Such names violate Microsoft naming conventions. Always renames such object using some semantically meaningful names.

Background:
Please see my past answers on the topic:
Problem with Treeview Scanner And MD5[^],
Control.Invoke() vs. Control.BeginInvoke()[^].

—SA


这篇关于尝试使用多线程添加控件时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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