如何从其他线程向列表框中添加项目?

5
我要开一个新的帖子:
Thread t = new Thread(UpdateListOutput);    
t.IsBackground = true;    
t.Start();

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

我收到错误信息:
“跨线程操作无效:从创建它的线程以外的线程访问控件 'OutputBox'。”
我该如何运行它?

1
可能是重复的问题:从单独的线程访问表单控件 - dparsons
3个回答

17

试一试

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

这也在单声道中起作用。当从多个线程更新列表框时,我会收到“xcb_xlib_too_much_data_requested”错误,而这已经解决了。谢谢。 - kodmanyagha

0

试试这个

void UpdateListOutput()
    {

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

            }));


    }

-1
我有一个方法seleniumCode(),它使用Selenium的“chromedriver”来进行某些操作。此方法通过单击GUI上的按钮来调用,该按钮使用执行的主线程。当此方法正在运行时,GUI被“阻塞”,因为主线程被seleniumCode()崩溃了。为了使这个工作正确,我是这样调用seleniumCode()的:
Thread th = new Thread(new ThreadStart(seleniumCode));
th.Start();

这是问题所在:我在seleniumCode()中有一些对'writeLbx("each string")'的调用。但是我无法写入ListBox,因为它来自另一个线程。所以,在经过两周的头痛之后,我来到了这里。
我选取了你的一些代码部分来制作这个:
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
@Yunnosch 这是一个类似的例子,就像你所说的。同样的问题(如何从其他线程向ListBox添加项目),但是我用自己的方式找到了解决方案。有问题的用户将不得不考虑如何在他的代码中实现我的解决方案。这只是帮助,你知道吗?我的方法有效,也许对他也有效呢? - Sergio Quinteiro
请查看[tour]和[answer]。您似乎误解了StackOverflow的概念,这是一个问题/答案收集网站,而不是问题和类似问题的讨论集合。您说:“有问题的用户将不得不考虑如何使我的解决方案适用于他的代码”,这意味着您没有讨论他的问题并描述您的经验如何帮助解决该问题。相反,您描述了自己的问题和解决方案,并期望其他人将其转移到此页面顶部的问题上。请删除与此无关的回答,或将其作为回答此问题的回答。 - Yunnosch
你可以用条件语句来回答,比如“如果你的问题是由于...引起的,那么解决方案就是...因为...”。但请不要像这样说:“我有一个类似但不同的问题,也许你可以从中学到一些东西,也许不行。” - Yunnosch

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