有关 C#.NET BackgroundWorker 的帮助

发布于 2024-11-30 16:47:05 字数 2628 浏览 1 评论 0原文

我正在尝试在我的应用程序中使用 BackgroundWorker 进行一个非常简单的测试。我可以看到后台工作人员正在做它的事情,但由于某种原因主线程正在收到任何进度通知。

我一定在这里遗漏了一些非常基本的东西。有人能指出我哪里出错了吗?

这是我的简单测试的代码:

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

然后这是我在输出窗口上得到的内容。它表明工作线程正在醒来并做它的事情,但主线程没有得到任何进度更新:

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).

I'm trying a very simple test for using BackgroundWorker in my app. I can see that the background worker is doing it's thing but for some reason the main thread is getting any progress notifications.

I must be missing something very basic here. Can anybody point out where I'm going wrong?

Here's the code for my simple test:

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

And then here is what I get on the output window. It shows that the worker is waking up and doing its thing but the main thread isn't getting any progress updates:

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

楠木可依 2024-12-07 16:47:05

这听起来像是一个愚蠢的问题,但您确定回调函数已绑定到 ProgressChanged 事件吗?

以下代码:

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

将输出以下内容:

[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

This may sound like a stupid question but are you sure the callback function is bound to the ProgressChanged event ?

The following code:

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

will output the following:

[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
猫性小仙女 2024-12-07 16:47:05

您的代码中缺少对 ProgressChanged 事件的订阅:

backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;

Subscription to ProgressChanged event is missing in your code:

backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;

秋心╮凉 2024-12-07 16:47:05

您是否在某处缺少 EventHandler 分配?我在这里没有看到一个。

我敢打赌您缺少一些如下所示的设计器代码:

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

这是使用拖放 GUI 自动生成的代码的问题。当它被破坏时,人们不知道如何解决它。

尝试删除BackgroundWorker并重新开始。

Are you missing an EventHandler assignment somewhere? I don't see one here.

I'm betting you are missing some designer code that looks like the following:

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

This is the problem with using auto-generated code from drag and drop GUIs. When it gets munged, people don't know how to fix it.

Try deleting the BackgroundWorker and starting over.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文