0
using System;
using System.ComponentModel;
using System.Net;
using System.Windows.Forms;
using Ionic.Zip;

namespace downloader
{
    public partial class GUI : Form
    {
        string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

        public GUI()
        {
            InitializeComponent();
        }

        private void Download_Click(object sender, EventArgs e)
        {
            label1.Text = ("Downloading...");
            WebClient x = new WebClient();
            x.DownloadProgressChanged += new DownloadProgressChangedEventHandler(x_DownloadProgressChanged);
            x.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(x_DownloadFileCompleted);
            x.DownloadFileAsync(new Uri("http://google.com/"), desktop + "\\index.html");
            download.Enabled = false;
        }

        void x_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            label2.Text = null;
            label1.Text = "Download Complete.";
            MessageBox.Show("Download Done.", "Done!");
        }

        public void x_DownloadProgressChanged(Object sender, DownloadProgressChangedEventArgs e)
        {
            progressBar.Value = e.ProgressPercentage;
            this.Text = ":: Kyle :: " + e.ProgressPercentage + "%";
            label2.Text = e.BytesReceived + " bytes saved.";
        }

        public void unzip(String zFile)
        {
            Ionic.Zip.ZipFile zip = Ionic.Zip.ZipFile.Read(zFile);
            zip.ExtractProgress += new EventHandler<ExtractProgressEventArgs>(zip_ExtractProgress);
            zip.ExtractAll(desktop, ExtractExistingFileAction.OverwriteSilently);
            zip.Dispose();
            zip = null;
        }

        public void zip_ExtractProgress(object sender, ExtractProgressEventArgs e)
        {

            if (e.EventType == ZipProgressEventType.Extracting_EntryBytesWritten)
            {
                this.label2.Text = e.BytesTransferred.ToString(); //unsafe also?
            }
            else if (e.EventType == ZipProgressEventType.Extracting_BeforeExtractEntry)
            {
                this.label3.Text = e.CurrentEntry.FileName; //unsafe
            }
        }

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

        private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
            unzip(desktop + "\\Client.zip");
        }

        void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            button1.Enabled = true;
            MessageBox.Show("Done Unzipping.");
        }

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

How do I fix my text labels? I'm using a backgroundWorker and it works without the labels but when I have em it keeps saying Cross-thread operation not valid: Control 'label3' accessed from a thread other than the thread it was created on.

Kyle
  • 3,004
  • 15
  • 52
  • 79

1 Answers1

1

You should report the progress by calling the BackgroundWorker's ReportProgress method.

Alternatively, you can run on the UI thread by calling BeginInvoke.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Which method would you recommend most for better performance in the main UI? – Kyle Jan 09 '11 at 03:16
  • I just noticed my backgroundWorker progress bar isn't updating the UI. DO you know what I could do to fix that too? – Kyle Jan 09 '11 at 03:21
  • They will both perform identically. – SLaks Jan 09 '11 at 03:28
  • You need to call `ReportProgress`. The BackgroundWorker doesn't magically know about the progress. – SLaks Jan 09 '11 at 03:29
  • I added backgroundWorker1.ReportProgress(e.ProgressPercentage); to the backgroundworker1_progresschanged but I'm unsure now how to view the value. Thanks for the help. – Kyle Jan 09 '11 at 03:33
  • You need to call `ReportProgress` to report changes to the progress. See the documentation. http://msdn.microsoft.com/en-us/library/a3zbdb1t.aspx – SLaks Jan 09 '11 at 03:34