Bantuan dengan C#.NET BackgroundWorker

Saya mencoba tes yang sangat sederhana untuk menggunakan BackgroundWorker di aplikasi saya. Saya dapat melihat bahwa pekerja latar belakang melakukan hal itu tetapi karena alasan tertentu thread utama mendapat pemberitahuan kemajuan.

Saya pasti melewatkan sesuatu yang sangat mendasar di sini. Adakah yang bisa menunjukkan kesalahan saya?

Berikut kode untuk tes sederhana saya:

namespace TestBackgroundWorker
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            progressBar1.Maximum = 100;
            progressBar1.Minimum = 0;
            progressBar1.Value = 0;
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.RunWorkerAsync();
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            int progress = 0;
            while (true)
            {
                Thread.Sleep(1000);
                System.Diagnostics.Debug.WriteLine("worker: progress={0}", progress);
                worker.ReportProgress(progress);
                progress = (progress + 10) % 100;
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("main: process progress={0}", e.ProgressPercentage);
            progressBar1.Value = e.ProgressPercentage;
        }
    }
}

Dan inilah yang saya dapatkan di jendela keluaran. Ini menunjukkan bahwa pekerja sudah bangun dan melakukan tugasnya tetapi thread utama tidak mendapatkan pembaruan kemajuan apa pun:

worker: progress=0
worker: progress=10
worker: progress=20
worker: progress=30
worker: progress=40
worker: progress=50
worker: progress=60
worker: progress=70
worker: progress=80
worker: progress=90
worker: progress=0
worker: progress=10
worker: progress=20
worker: progress=30
worker: progress=40
worker: progress=50
worker: progress=60
worker: progress=70
worker: progress=80
The thread '<No Name>' (0x1e84) has exited with code 0 (0x0).
worker: progress=90
worker: progress=0
worker: progress=10
worker: progress=20
worker: progress=30
worker: progress=40
worker: progress=50
worker: progress=60
worker: progress=70
worker: progress=80
worker: progress=90
worker: progress=0
worker: progress=10
worker: progress=20
worker: progress=30
worker: progress=40
worker: progress=50
worker: progress=60
worker: progress=70
worker: progress=80
worker: progress=90
worker: progress=0
worker: progress=10
worker: progress=20
worker: progress=30
worker: progress=40
worker: progress=50
The thread 'vshost.RunParkingWindow' (0x2760) has exited with code 0 (0x0).
The thread '<No Name>' (0x29c8) has exited with code 0 (0x0).
The program '[3528] TestBackgroundWorker.vshost.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).

person Denis    schedule 22.08.2011    source sumber


Jawaban (3)


Ini mungkin terdengar seperti pertanyaan bodoh tetapi apakah Anda yakin fungsi panggilan balik terikat pada acara ProgressChanged?

Kode berikut:

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;

namespace ConsoleApplication2
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            new Program().Run();
        }

        void Run()
        {
            var worker = new BackgroundWorker { WorkerReportsProgress = true };

            worker.ProgressChanged += WorkerOnProgressChanged;
            worker.DoWork += WorkerOnDoWork;
            worker.RunWorkerAsync();

            Console.ReadKey();
        }

        private void WorkerOnDoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; ; i++)
            {
                Debug.WriteLine("[Thread #{0,2} (worker)] Progress:{1}", Thread.CurrentThread.ManagedThreadId, i);
                (sender as BackgroundWorker).ReportProgress(i);
                Thread.Sleep(1000);
            }
        }

        private void WorkerOnProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Debug.WriteLine("[Thread #{0,2} (main  )] Progress:{1}", Thread.CurrentThread.ManagedThreadId, e.ProgressPercentage);
        }
    }
}

akan menampilkan yang berikut:

[Thread # 7 (worker)] Progress:0
[Thread #11 (main  )] Progress:0
[Thread # 7 (worker)] Progress:1
[Thread #11 (main  )] Progress:1
[Thread # 7 (worker)] Progress:2
[Thread #11 (main  )] Progress:2
[Thread # 7 (worker)] Progress:3
[Thread #11 (main  )] Progress:3
[Thread # 7 (worker)] Progress:4
[Thread #11 (main  )] Progress:4
[Thread # 7 (worker)] Progress:5
[Thread #11 (main  )] Progress:5
[Thread # 7 (worker)] Progress:6
[Thread #11 (main  )] Progress:6
[Thread # 7 (worker)] Progress:7
[Thread #11 (main  )] Progress:7
[Thread # 7 (worker)] Progress:8
[Thread #12 (main  )] Progress:8
person edvaldig    schedule 22.08.2011
comment
Seperti yang saya katakan, saya berasumsi itu akan menjadi sesuatu yang sangat mendasar dan memang demikian. Anda menghasilkan banyak uang. Terima kasih! - person Denis; 22.08.2011

Berlangganan acara ProgressChanged tidak ada dalam kode Anda:

backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;

person Alex F    schedule 22.08.2011
comment
Menarik. Saya mengikuti contoh pertama pada dokumentasi MSDN (lihat //msdn.microsoft.com/en-us/library/) dan pada contoh pertama, mereka tidak menyebutkan apa pun tentang berlangganan penangan ProgressChanged. Namun, setelah Anda menyebutkannya, saya dapat melihat bahwa contoh kedua (contoh Fibonacci) juga demikian. - person Denis; 22.08.2011

Apakah Anda melewatkan tugas EventHandler di suatu tempat? Saya tidak melihatnya di sini.

Saya yakin Anda melewatkan beberapa kode desainer yang terlihat seperti berikut:

this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);

Ini adalah masalah dengan penggunaan kode yang dibuat secara otomatis dari GUI drag and drop. Ketika rusak, orang tidak tahu bagaimana cara memperbaikinya.

Coba hapus BackgroundWorker dan mulai lagi dari awal.

person rstackhouse    schedule 22.08.2011
comment
Ya. Mengikat event handler adalah satu-satunya hal yang saya lewatkan. Terima kasih. - person Denis; 22.08.2011