C# 我可以使用后台线程向列表框添加值吗?

发布于 2024-07-11 11:46:07 字数 173 浏览 10 评论 0原文

我希望我的后台工作人员将项目添加到列表框中,在调试时似乎是这样做的,但列表框不显示值。 我怀疑这与在后台工作线程内添加项目有关,我是否需要将这些项目添加到数组中,然后在 backgroundWorker1_RunWorkerCompleted 期间从数组填充列表框?

谢谢您的帮助。

I want my background worker to add items to a list box, it appears to do so when debugging but the listbox doesn't show the values. I suspect this is something to do with adding items whilst inside the background worker thread, do I need to add these to an array and then populate the list box from the array during backgroundWorker1_RunWorkerCompleted?

Thanks for the help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

想你只要分分秒秒 2024-07-18 11:46:07

您可以像这样使用 Invoke:

private void AddToListBox(object oo)
{
    Invoke(new MethodInvoker(
                   delegate { listBox.Items.Add(oo); }
                   ));
}

You can use Invoke like this:

private void AddToListBox(object oo)
{
    Invoke(new MethodInvoker(
                   delegate { listBox.Items.Add(oo); }
                   ));
}
幼儿园老大 2024-07-18 11:46:07

您可以,但您必须建议您的后台工作人员报告状态,并将具有当前状态的框的输入发送到该事件。 在该事件的方法中,您可以访问该框并放入新值。

否则您需要手动调用。

 public Form1()
        {
            InitializeComponent();

            BackgroundWorker bw = new BackgroundWorker();
            bw.WorkerReportsProgress = true;
            bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerAsync();
        }

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                ((BackgroundWorker)sender).ReportProgress(0, i.ToString());
            }
        }

        void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            listBox1.Items.Add((string)e.UserState);
        }

You can, but you must advise your Backgroundworker to report state, and send the input for the box with the current state to that event. In the method for that event, you can access the box and put the new value in.

Otherwise you need to invoke manually.

 public Form1()
        {
            InitializeComponent();

            BackgroundWorker bw = new BackgroundWorker();
            bw.WorkerReportsProgress = true;
            bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerAsync();
        }

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                ((BackgroundWorker)sender).ReportProgress(0, i.ToString());
            }
        }

        void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            listBox1.Items.Add((string)e.UserState);
        }
此生挚爱伱 2024-07-18 11:46:07

我添加了如下所示的函数,以便可以从主线程或后台线程将项目添加到列表框中。 该线程检查是否需要 Invoke,然后在需要时使用 Invoke。

  delegate void AddListItemDelegate(string name,object otherInfoNeeded);

  private void
     AddListItem(
        string name,
        object otherInfoNeeded
     )
  {
     if (InvokeRequired)
     {
        BeginInvoke(new AddListItemDelegate(AddListItem), name, otherInfoNeeded
        return;
     }

     ... add code to create list box item and insert in list here ...
  }

I add functions like the following so that I can add items to the list box from either the main thread or background threads. Thi thread checks if a Invoke is necessary and then uses Invoke if it is necessary.

  delegate void AddListItemDelegate(string name,object otherInfoNeeded);

  private void
     AddListItem(
        string name,
        object otherInfoNeeded
     )
  {
     if (InvokeRequired)
     {
        BeginInvoke(new AddListItemDelegate(AddListItem), name, otherInfoNeeded
        return;
     }

     ... add code to create list box item and insert in list here ...
  }
稀香 2024-07-18 11:46:07

您可以通过以下方式在后台线程上添加它们:

Form.Invoke

Form.BeginInvoke

将调用从后台线程编组到主 UI 线程所需的。
不过我很确定BackgroundWorker 提供了一个在Foreground 线程上自动调用的事件,并且您应该能够毫无问题地更新此事件。
这是“ProgressChanged”,可以由后台工作进程通过调用 ReportProgress 来触发。

您是否也尝试过在列表框中调用 .Refresh()

You can add them while on a background thread via:

Form.Invoke

or

Form.BeginInvoke

which are required to marshall the call from a background thread to a main UI thread.
However I'm pretty sure BackgroundWorker offers an event that automatically gets called on the Foreground thread and you should be able to update on this event without any problems.
This is "ProgressChanged" which can be fired by the background worker process by calling ReportProgress.

Have you tried calling .Refresh() on the listbox as well?

冬天的雪花 2024-07-18 11:46:07

如果您正在尝试更新数据库。 我建议从列表框中创建一个数据集。

例如,如果您对数据库中的每个项目执行某些操作。 通过创建新数据集并通过 mainDataset 声明来复制数据库数据集。

例如:
// gridview数据集是dataset1

BackgroundWorker_DoWork(object sender, DoWorkArgs e)
{
     Dataset dataset2 = dataset1;
     foreach(DataGridViewRow row in GridView)
     {
         //do some work
         dataset2.Main.AddMainRow(values to add);
         dataset2.AcceptChanges();
     }
}


BackgroundWorker_WorkCompleted(object sender, DoWorkArgs e)
{
    //Forces UI thread to valitdate dataset
    dataset2.update();

    // Sets file Path
    string FilePath = "Some Path to file";

    dataset2.writexml(FilePath, XmlWriteOptions.WriteSchema);

    //if you use xml to fill your dataset filepath to write should equal path to dataset1 xml
    dataset1.Refresh();
}

if you are trying to update a database. From a listbox i would suggest creating a dataset.

for instance, if your doing something for each item in a database. Copy the database dataset, by creating new dataset and declaring by mainDataset.

for example:
// the gridview dataset is dataset1

BackgroundWorker_DoWork(object sender, DoWorkArgs e)
{
     Dataset dataset2 = dataset1;
     foreach(DataGridViewRow row in GridView)
     {
         //do some work
         dataset2.Main.AddMainRow(values to add);
         dataset2.AcceptChanges();
     }
}


BackgroundWorker_WorkCompleted(object sender, DoWorkArgs e)
{
    //Forces UI thread to valitdate dataset
    dataset2.update();

    // Sets file Path
    string FilePath = "Some Path to file";

    dataset2.writexml(FilePath, XmlWriteOptions.WriteSchema);

    //if you use xml to fill your dataset filepath to write should equal path to dataset1 xml
    dataset1.Refresh();
}
心安伴我暖 2024-07-18 11:46:07

Application.Doevents() 函数将解决该问题。

Application.Doevents() function will solve the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文