简体   繁体   English

使用进度条复制项目

[英]Copy items using progress bar

I am copying large files from one place to another. 我正在将大文件从一个地方复制到另一个地方。 It is taking a long time so I decided to use a progress bar. 这花了很长时间,所以我决定使用进度条。

I am following this example . 我正在关注这个例子

The copyItems() function iterates through the list items and copies the items from another place. copyItems()函数遍历列表项并从另一个位置复制这些项。 It in turn calls a function CopyListItem which copies one item . 它依次调用复制一个项目的函数CopyListItem。

I need to tie the backgroundWorker1.ReportProgress(i) to the total no of items ie itemcoll. 我需要将backgroundWorker1.ReportProgress(i)绑定到项目总数,即itemcoll。

I do not want to use thread.sleep() . 我不想使用thread.sleep()

The progress bar needs to show the actual time required to copy the file from one place to another. 进度条需要显示将文件从一个位置复制到另一位置所需的实际时间。

The Progress bar needs to progress when only when one file is copied. 当复制一个文件 ,进度条才需要进度 IT needs to complete when all the files are copied 复制所有文件 ,IT 需要完成

using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, System.EventArgs e)
        {
            // Start the BackgroundWorker.
            backgroundWorker1.RunWorkerAsync();
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 1; i <= itemscoll.count; i++)
            {
                // Wait 100 milliseconds.
                Thread.Sleep(100);
                // Report progress.
                backgroundWorker1.ReportProgress(i);
            }
        }
        private void CopyListItem(SPListItem sourceItem, string destinationListName, string destServerURL)
        {
            // copy items
        }
        private void copyitems()
        {
            try
            {
                int createdYear = 0;
                backgroundWorker1.RunWorkerAsync();
                foreach (SPListItem sourceItem in itemscoll)
                {
                    if (Helper.year == createdYear)
                    {
                        CopyListItem(sourceItem, Helper.destinationListName,Helper.destServerURL);
                        DeleteItem(CompRefNo);
                    }
                }
            }
            catch()
            {}
        }
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Change the value of the ProgressBar to the BackgroundWorker progress.
            progressBar1.Value = e.ProgressPercentage;
            // Set the text.
            this.Text = e.ProgressPercentage.ToString();
        }
    }
}

You need to do your copy-action in the DoWork-Event of the BackgroundWorker . 您需要在BackgroundWorker的DoWork-Event中执行复制操作。 So when you call the backgroundWorker1.RunWorkerAsync() you'll have to pass an object to it containing all the needed informations. 因此,当您调用backgroundWorker1.RunWorkerAsync() ,必须将包含所有必需信息的对象传递给它。 This could be something like: 可能是这样的:

internal class WorkerItem
{
    public WorkerItem(List<SPListItem> spListItems, string destinationListName, string destinationServerURL)
    {
        SPListItems = new List<SPListItem>(spListItems);
        DestinationListName = destinationListName;
        DestinationServerURL = destinationServerURL;
    }

    public List<SPListItem> SPListItems { get; private set; }
    public string DestinationListName { get; private set; }
    public string DestinationServerURL { get; private set; }
}

The call of RunWorkerAsync can look something like: RunWorkerAsync的调用可能类似于:

backgroundWorker1.RunWorkerAsync(new WorkerItem(...));

In your DoWork-Handler you than have to get this object from the e.Argument and cast it to WorkerItem . 在你的DoWork处理程序比你必须从一开始这个对象e.Argument并转换为WorkerItem Than you can work with it like: 比您可以像这样使用它:

private void BackgroundWorker1OnDoWork(object sender, DoWorkEventArgs e)
{
    WorkerItem workerItem = (WorkerItem)e.Argument;

    for (int i = 0; i < workerItem.SPListItems.Count(); i++)
    {
        // CopyListItem is doing the copy for one item.
        CopyListItem(workerItem.SPListItems[i], workerItem.DestinationListName, workerItem.DestinationServerURL);
        ((BackgroundWorker)sender).ReportProgress(i + 1);
    }
}

The ProgressChanged-Handler only increments the value of the ProgressBar : ProgressChanged-Handler仅增加ProgressBar的值:

private void BackgroundWorker1OnProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

If you want to have more informations in the ProgressChanged-Handler you can pass an additional object as UserState. 如果要在ProgressChanged-Handler中具有更多信息,则可以传递一个附加对象作为UserState。 This you can get by object additional = e.UserState; 您可以通过object additional = e.UserState;获得object additional = e.UserState;

Right before you call backgroundWorker1.RunWorkerAsync(new WorkerItem(...)) you should set the Maximum of progressBar1 to the amount of SPListItems like: 在调用backgroundWorker1.RunWorkerAsync(new WorkerItem(...)) ,应将progressBar1的Maximum设置为SPListItems的数量,例如:

progressBar1.Maximum = itemscoll.Count;

Your BackgroundWorker only reports it's progress to you if you set. 如果设置, BackgroundWorker只会向您报告进度。

backgroundWorker1.WorkerReportsProgress = true;

If you want to be informed when the BackgroundWorker is finished you can get the RunWorkerCompleted-Event. 如果要在BackgroundWorker完成时收到通知,则可以获取RunWorkerCompleted-Event。

backgroundWorker1.RunWorkerCompleted += BackgroundWorker1OnRunWorkerCompleted;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM