Arreglando llamadas seguras para subprocesos desde backgroundWorker

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.

preguntado el 09 de enero de 11 a las 03:01

1 Respuestas

You should report the progress by calling the BackgroundWorker's ReportProgress método.

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

Respondido el 09 de enero de 11 a las 06:01

Which method would you recommend most for better performance in the main UI? - Kyle

I just noticed my backgroundWorker progress bar isn't updating the UI. DO you know what I could do to fix that too? - Kyle

They will both perform identically. - SLaks

Necesitas llamar ReportProgress. The BackgroundWorker doesn't magically know about the progress. - SLaks

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

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.