修复来自backgroundWorker的线程安全调用

时间:2011-01-09 03:08:57

标签: c# backgroundworker invokerequired

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

如何修复文字标签?我正在使用backgroundWorker,它在没有标签的情况下工作,但是当我有它时,它会一直说Cross-thread operation not valid: Control 'label3' accessed from a thread other than the thread it was created on.

1 个答案:

答案 0 :(得分:1)

您应该通过调用BackgroundWorker的ReportProgress方法来报告进度。

或者,您可以通过调用BeginInvoke来运行UI线程。