在 C# 中使用后台工作者?

using the Background Worker in C#?

我的应用程序的一部分可以从预定义文件夹加载图像。此时加载图像需要更多时间。现在我想通了,可以让我告诉加载进度的进度条。

我遇到的问题是: 我无法将 BackgroudWorker、Progress Bar 与我的功能集成。 例如,以下是后台工作人员和进度条码:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    // Load file list here
    int totalImageCount = 10000;
    // Set maximum value of the progress bar
    progressBar1.Invoke(new Action(() => { progressBar1.Maximum = totalImageCount; }));

    for (int i = 0; i < totalImageCount; i++)
    {
        // Load a single image here
        Thread.Sleep(10);

        // User cancelled loading (form shut down)
        if (e.Cancel) return;
        // Set the progress
        progressBar1.Invoke(new Action(() => { progressBar1.Value = i; }));
    }

    // Cleanup here
}

// Starts the loading
private void button1_Click(object sender, EventArgs e)
{
    // Start loading images
    backgroundWorker1.WorkerSupportsCancellation = true;
    backgroundWorker1.RunWorkerAsync();
}

// Stops the loading
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    // Stop the loading when the user closes the form
    if (backgroundWorker1.IsBusy) backgroundWorker1.CancelAsync();
}

以下是Progress Bar需要的函数

 private void LoadImages()
    {
    string imagesPath = (Application.StartupPath + "/UnknownFaces/");
                    string[] extensions = new[] { ".jpg", ".jpeg", ".png" };
                    var allfiles = Directory.GetFiles(imagesPath);
                    this.imageList1.ImageSize = new Size(256, 250);
                    this.imageList1.ColorDepth = ColorDepth.Depth32Bit;
                    foreach (FileInfo fileInfo in filesSorted)
                    {
                        try
                        {
                            this.imageList1.Images.Add(fileInfo.Name,
                                                     Image.FromFile(fileInfo.FullName));
                        }
                        catch
                        {
                            Console.WriteLine(fileInfo.FullName + "  is is not a valid image.");
                        }
                    }
                    this.lstView_un.View = View.LargeIcon;
                    lstView_un.LargeImageList = this.imageList1;
                    lstView_un.Items.Clear();
                    for (int j = 0; j < this.imageList1.Images.Count; j++)
                    {
                        ListViewItem item = new ListViewItem();
                        item.ImageIndex = j;
                        item.Text = imageList1.Images.Keys[j].ToString();
                        this.lstView_un.Items.Add(item);
                    }

                }
                catch (Exception ex)
                {
                    MessageBox.Show("Something Wrong happen! "+ex.Message);
                }
    }

我觉得主要的套路作品有:

 this.lstView_un.View = View.LargeIcon;
                lstView_un.LargeImageList = this.imageList1;
                lstView_un.Items.Clear();
                for (int j = 0; j < this.imageList1.Images.Count; j++)
                {
                    ListViewItem item = new ListViewItem();
                    item.ImageIndex = j;
                    item.Text = imageList1.Images.Keys[j].ToString();
                    this.lstView_un.Items.Add(item);
                }

代码中最慢的部分实际上是读取文件的循环,而不是填充 ListView.

的循环

BackgroundWorker 报告或以其他方式在 UI 中呈现进度状态的最佳方法是使用 ProgressChanged 事件。但是,您正在使用的代码示例也可以正常工作。也就是说,只需直接从您的工作代码更新 ProgressBar 对象。它无法充分利用 BackgroundWorker 提供的功能(事实上,如果您不打算使用它的功能,为什么还要麻烦 BackgroundWorker 的问题),但它会起作用。

例如:

var allfiles = Directory.GetFiles(imagesPath);
this.imageList1.ImageSize = new Size(256, 250);
this.imageList1.ColorDepth = ColorDepth.Depth32Bit;

// Set the maximum value based on the number of files you get
progressBar1.Invoke((MethodInvoker)(() => { progressBar1.Maximum = filesSorted.Count(); }));

foreach (FileInfo fileInfo in filesSorted)
{
    try
    {
        this.imageList1.Images.Add(fileInfo.Name,
        Image.FromFile(fileInfo.FullName));
    }
    catch
    {
        Console.WriteLine(fileInfo.FullName + "  is is not a valid image.");
    }

    // Update the ProgressBar, incrementing by 1 for each iteration of the loop
    progressBar1.Invoke((MethodInvoker)(() => progressBar1.Increment(1)));
}

注意:您的代码示例不完整,即使作为片段也没有意义。一个特别的问题是您将文件名检索到数组 allfiles 中,但您正在迭代一个完全不同的集合 filesSorted。我已尽最大努力使用您提供的代码,但由于您发布的代码无法按原样工作,您可能需要对我提供的示例进行一些小的调整才能使其执行您的操作想要。

如果您无法根据上述内容解决这个问题,请提供 a good, minimal, complete code example 可靠地说明您的场景以及您在弄清楚什么方面遇到的问题。