C#使用backgroundworker进程更新并附加文本框值

Pet*_*ell 14 c# backgroundworker

我有一个ac #windows form app我一起扔了.这很简单:

输入:

  • 文字字符串
  • 源文件夹路径
  • 目标文件夹路径
  • 整数计数

该应用程序搜索源文件夹中的文本文件以查找输入的文本字符串; 如果找到该字符串,则将该文件和具有相同名称的图像文件复制到目标文件夹.它会根据整数输入多次执行此操作.

所以我有一个按钮,在按钮点击事件中我打电话

ProcessImages(tbDID.Text, tbSource.Text, tbDest.Text, comboBoxNumberImages.SelectedItem.ToString());
Run Code Online (Sandbox Code Playgroud)

这是:

private void ProcessImages(string DID, string SourceFolder, string DestFolder, string strNumImages)
        {         
            int ImageCounter = 0;
            int MaxImages = Convert.ToInt32(strNumImages);

            DirectoryInfo di = new DirectoryInfo(SourceFolder);

            foreach (FileInfo fi in di.GetFiles("*.txt"))
            {
                if (fi.OpenText().ReadToEnd().Contains(DID))
                {
                    //found one!
                    FileInfo fi2 = new FileInfo(fi.FullName.Replace(".txt", ".tif"));
                    if (fi2.Exists)
                    {
                        try
                        {
                            tbOutput.Text += "Copying " + fi2.FullName + " to " + tbDest.Text + "\r\n";
                            fi2.CopyTo(tbDest.Text + @"\" + fi2.Name, true);
                            tbOutput.Text += "Copying " + fi.FullName + " to " + tbDest.Text + "\r\n";
                            fi.CopyTo(tbDest.Text + @"\" + fi.Name, true);

                            ImageCounter++;
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message);
                        }
                    }
                }

                if (ImageCounter >= MaxImages)
                    break;

            }

        }
Run Code Online (Sandbox Code Playgroud)

会发生什么是流程运行正常,但我想在复制文件时更新表单上的文本框.基本上表单在运行时会消隐,在完成后输出在文本框中.我想实现一个BackgroundWorker让它在运行时更新UI.

我查看了这些示例,但并未真正关注它们.我没有百分比完整值,我只想更新.Text更改每次迭代并显示它.我甚至不认为我必须将实际的复制操作放在不同的线程中,它听起来像是需要与主UI线程分开运行.也许我完全把这复杂化......有人能把我推向正确的方向吗?谢谢!

Rya*_*ver 14

你和背景工作者在正确的轨道上.这是我放在一起向您展示如何执行此操作的示例.使用Form1创建一个新的Windows应用程序.添加4个控件:label1,backgroundWorker1,button1和button2.然后使用此代码隐藏.然后,您可以使用ReportProgress userState向主线程报告您想要的任何内容.在这个例子中,我传递一个字符串.然后,ProgressChanged事件处理程序位于UI线程上,并更新文本框.

    public partial class Form1 : Form
{
    int backgroundInt;
    public Form1()
    {
        InitializeComponent();
        backgroundWorker1.WorkerReportsProgress = true;
    }

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        label1.Text = e.UserState as string;
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        backgroundInt = 1;
        while (backgroundWorker1.CancellationPending == false)
        {
            System.Threading.Thread.Sleep(500);
            backgroundWorker1.ReportProgress(0, 
                String.Format("I found file # {0}!", backgroundInt));
            backgroundInt++;
        }
    }


    private void button1_Click(object sender, EventArgs e)
    {
        backgroundWorker1.RunWorkerAsync();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        backgroundWorker1.CancelAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 就OP的原始"我没有百分比"投诉而言,重要的一点是ReportProgress不仅可以采用百分比,而且*也可以采用*通用对象 - 这可以(如本例中所示)是一个串. (4认同)

Sis*_*utl 7

如果使用后台工作程序,则可以使用ReportProgress方法返回任何整数,例如处理的记录数.它不一定是百分比.然后,在ProgressChanged处理程序中,您可以更新文本框.例如

int count = e.ProgressPercentage;
textBox1.Text = string.Format("{0} images processed.", count);
Run Code Online (Sandbox Code Playgroud)

如果您不想使用后台工作程序,可以在循环中调用Application.DoEvents().这将为UI提供刷新自身和响应用户操作的机会.但要注意 - 它会使你的程序变慢,所以你可能只想在每100次迭代时调用它.