在C#中使用Background Worker?

时间:2015-06-03 16:21:48

标签: c# progress-bar

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

我遇到的问题是: 我无法将BackgroudWorker,Progress Bar与我的功能集成在一起。 对于Instance,以下是Background worker和Progress条形码:

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();
}

以下是进度条所需的功能

 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);
                }

1 个答案:

答案 0 :(得分:1)

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

BackgroundWorker报告或以其他方式显示用户界面中的进度状态的最佳方法是使用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以及您在确定问题时遇到的问题。