Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
436 views
in Technique[技术] by (71.8m points)

c# - DotNetZip in BackgroundWorker update progressbar and label on a form

I'm creating option to backup data of my app with DotNetZip and to avoid freezing the app I've found that the best way for a this type of action best way is to use BackgroundWorker. So I came with something like this:

    private void processButton_Click(object sender, EventArgs e)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true;
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

        BackupParams bp = new BackupParams();
        bp.Source = inputTextBox.Text;  // source dir
        bp.Output = outputTextBox.Text; // output file
        bp.Password = @"Pa$$w0rd";

        worker.RunWorkerAsync(bp);
    }

    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show((string)e.Result, "Zip", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }

    void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {

    }

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        BackupParams bp = (BackupParams)e.Argument;

        string id = Guid.NewGuid().ToString();
        comment += "Created at: " + DateTime.Now.ToString() + "
";
        comment += id;

        ZipFile zf = new ZipFile();
        zf.Comment = comment;
        zf.CompressionMethod = CompressionMethod.BZip2;
        zf.CompressionLevel = CompressionLevel.BestCompression;

        zf.Encryption = EncryptionAlgorithm.WinZipAes256;
        zf.Password = bp.Password;

        zf.Name = bp.Output;

        zf.AddDirectory(bp.Source);

        zf.Save();

        e.Result = bp.Output;
    }

and this is BackupParams

public class BackupParams
{
    public string Source { get; set; }
    public string Output { get; set; }
    public string Password { get; set; }
}

And right now I'm stuck cause I want to show the progress (percentage with names) of files added to the archive. What is the best way to do this? I know i can use those methods from ZipFile

zf.SaveProgress += zf_SaveProgress;
zf.AddProgress += zf_AddProgress;

but from those I don't have access progressbar or label that are on form...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For sending a progress report out from a BackgroundWorker you use ReportProgress() inside your DoWork method.

void worker_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker theWorker = (BackgroundWorker)sender;
    theWorker.ReportProgress(0, "just starting");

    BackupParams bp = (BackupParams)e.Argument;
    ...

This then fires off your worker_ProgressChanged method, so you can take the report from there into your controls.

The trick is that you have to make another function to handle the progress change with your zip creation. You can't access your UI controls here because they are on a different thread. You should be able to create a lambda for this (and I don't know the exact parameters, please fix if I'm wrong)

zf.SaveProgress += (sender, eventArgs) => 
{
    // Check if EvenType equals Saving_AfterWriteEntry or NullReferenceException will be thrown
    if (eventArgs.EventType == ProgressEventType.Saving_AfterWriteEntry)
    {
        theWorker.ReportProgress(eventArgs.EntriesSaved, "Saving "+ eventArgs.CurrentEntry.FileName);
    }
};

zf.AddProgress += (sender, eventArgs) => 
{
    // Check if EventType equals Adding_afterAddEntry or NullReferenceException will be thrown
    if (eventArgs.EventType == ZipProgressEventType.Adding_afterAddEntry)
    {
        theWorker.ReportProgress(eventArgs.EntriesAdded, "Adding "+ eventArgs.CurrentEntry.FileName);
    }
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...