【问题标题】:How to add item to listBox from other thread?如何从其他线程将项目添加到列表框?
【发布时间】:2021-01-05 06:52:40
【问题描述】:

我要开新帖了:

Thread t = new Thread(UpdateListOutput);    
t.IsBackground = true;    
t.Start();

更新列表输出:

void UpdateListOutput()
{
    while (true)
    {
        if (!string.IsNullOrEmpty(engineOutput))
        {
            OutputBox.Items.Add(engineOutput);
        }
    }
}

我收到错误:

跨线程操作无效:从 线程不是创建它的线程。

我该如何运行它?

【问题讨论】:

标签: c# multithreading


【解决方案1】:

试试这个

this.Invoke((MethodInvoker)(() => OutputBox.Items.Add(engineOutput)));

【讨论】:

  • 这也适用于单声道。从多个线程更新列表框时出现 xcb_xlib_too_much_data_requested 错误,这已解决。谢谢。
【解决方案2】:

试试这个

void UpdateListOutput()
    {

            Dispatcher.BeginInvoke(new Action(() => {
                while (true)
                {
                    if (!string.IsNullOrEmpty(engineOutput))
                    {
                        OutputBox.Items.Add(engineOutput);
                    }
                }                

            }));


    }

【讨论】:

    【解决方案3】:

    我有一个方法seleniumCode(),它使用 Selenium 的“chromedriver”来做一些事情。此方法通过单击 de GUI 上的按钮调用,该按钮使用执行的主线程。当此方法运行时,GUI 被“阻塞”,因为主线程被 seleniumCode() 折叠。为了使这项工作正常进行,我这样调用 seleniumCode():

    Thread th = new Thread(new ThreadStart(seleniumCode));
    th.Start();
    

    问题是:我在 seleniumCode() 中调用了一些“writeLbx("each string")”。而且我不能在 ListBox 上写,因为它来自另一个线程。所以,经过 2 周的脑筋急转弯,我来到了这里。

    我选择了你的一些代码来做这个:

    private void writeLbx(string s)
    {
        switch (s)
        {
            case "Empezando_Tracking": lbxProcess.Items.Add("xxx");
                        break;
            case "Mi Cuenta": lbxProcess.Items.Add("xxx");
                        break;
            case "Email_Pass": lbxProcess.Items.Add("xxx");
                        break;
            case "Iniciar sesión": lbxProcess.Items.Add("xxx");
                        break;
            case "Procesando_Intento": lbxProcess.Items.Add("xxx");
                        break;
            case "Precio_OK": lbxProcess.Items.Add("xxx");
                        break;
            case "Poner_Cantidad": lbxProcess.Items.Add("xxx");
                        break;
        }
    
        lbxProcess.Update();
        lbxProcess.TopIndex = lbxProcess.Items.Count - 1;
    }
    

    ...进入这个:

    private void writeLbx(string s)
    {
    
        this.Invoke(new Action(() =>
        {
    
            switch (s)
            {
                case "Empezando_Tracking": lbxProcess.Items.Add("xxx");
                        break;
                case "Mi Cuenta": lbxProcess.Items.Add("xxx");
                        break;
                case "Email_Pass": lbxProcess.Items.Add("xxx");
                        break;
                case "Iniciar sesión": lbxProcess.Items.Add("xxx");
                        break;
                case "Procesando_Intento": lbxProcess.Items.Add("xxx");
                        break;
                case "Precio_OK": lbxProcess.Items.Add("xxx");
                        break;
                case "Poner_Cantidad": lbxProcess.Items.Add("xxx");
                        break;
            }
    
            lbxProcess.Update();
            lbxProcess.TopIndex = lbxProcess.Items.Count - 1;
    
        }));
    
    }
    

    而这种简单的改变就可以让我的代码按我想要的方式工作。

    【讨论】:

    • 这应该是解决页面顶部问题中描述的问题的答案吗?它读起来像“我有一个类似但仍然不同的问题,我通过......解决了。”
    • @Yunnosch 这是一个类似的例子,就像你说的。同样的问题(如何从其他线程将项目添加到 ListBox 中),但在我的方式上可行的解决方案。有问题的用户将不得不考虑如何让我的解决方案在他的代码上运行。只是帮助,你知道吗?我的方法行得通,也许对他也行得通¿?
    • 请参阅tourHow to Answer。你好像误解了StackOverflow的概念,就是做一个Q/A集合,而不是一个问题集合和类似问题的讨论。您说“有问题的用户必须考虑如何使我的解决方案在他的代码上运行。”,这意味着您不是在讨论他的问题并描述您的经验如何帮助解决这个问题。相反,你描述你的问题和你的解决方案,并让其他人转移到本页顶部的问题。请删除您不相关的答案或使其回答这个问题。
    • 你可以用一个有条件的答案来表达,比如“如果你的问题是由......引起的,那么解决方案是......因为......”但请不要说“我有一个类似但不同的问题,也许你可以从中学到一些东西,也许不是。”
    猜你喜欢
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多