c#backgroundWorker不会引发ProgressChanged或RunWorkerCompleted事件

时间:2011-05-24 09:39:42

标签: c# multithreading .net-3.5 backgroundworker

使用C#.NET 3.5。

似乎我不是唯一一个,因为搜索似乎提出了很多类似的问题,但是阅读它们似乎仍然缺少解决方案。

我正在点击我的用户界面点击一个事件,然后应该启动一个backgroundWorker以完成一些耗时的工作 - 在这种情况下,我希望它从表单中收集信息并且a)写到xml文件以及b)将信息插入远程数据库。

这正是backgroundWorker设计和打算做的事情。

以下是提升代码的事件。

private void btnFinish_Click(object sender, EventArgs e)
{
    clkFinish.setInstant();
    curAct.setTimeFinish(DateTime.Now);
    btnStart.Enabled = true;
    bgwDataWorker.RunWorkerAsync();
    for (int i = 0; i < 20; i++)
    {
        Console.WriteLine("Thread a: " + i);
        Thread.Sleep(100);
        if (i == (20 - 1))
        {
            Console.WriteLine("Finished");
        }
    }

}

正如你所看到的,我在那里有一些代码,我用它来作为背景工作者代码的平衡,在这里:

private void bgwDataWorker_DoWork(object sender, DoWorkEventArgs e)
{
    Console.WriteLine("Running in a different thread now");
    int count = 0;
    for (int i = 0; i < 21; i++)
    {
        Console.WriteLine("Thread b: " + i);
        Thread.Sleep(100);
        (sender as BackgroundWorker).ReportProgress(5 * i, null);
        if (i == (21 - 1))
        {
            count = i;
        }
    }
    e.Result = count;
}

到目前为止,一切似乎都在努力。

我的问题是,当DoWork方法中的代码完成时,什么也没发生。以下是ProgressChanged和RunWorkerComplete方法。

private void bgwDataWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    Console.WriteLine(e.ProgressPercentage);
}

private void bgwDataWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    Console.WriteLine("Result is " + e.Result.ToString());

}

这令我感到困惑。

我尝试过运行examples from MSDN而我遇到了同样的问题。 RunWorkerCompleted和ReportProgress事件由于某种原因根本没有被提出,我不明白为什么。

感谢阅读。

艾伦

7 个答案:

答案 0 :(得分:5)

您没有错过设置这些变量,是吗?

backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;

也可能是DoWork-Method中的一个例外,它没有被处理。

答案 1 :(得分:5)

我遇到了同样的问题,我只是想出了答案。

在backgroundworker的属性中,确保ProgressChanged和RunWorkerCompleted列出其功能的名称(我的名称分别称为'backgroundWorker1_ProgressChanged'和'backgroundWorker1_RunWorkerCompleted')。

答案 2 :(得分:3)

Inksmithy,你提到你已经重命名了BackgroundWorker。请注意,执行此操作时,Forms Designer不会自动更改对旧DoWork和RunWorkerCompleted方法的引用。因此,在Forms设计器中,单击BackgroundWorker,然后单击“属性”窗口中的“事件”图标(闪电),并仔细检查它是否指向正确的事件方法名称。

答案 3 :(得分:1)

WorkerReportsProgress属性设置为True。

答案 4 :(得分:0)

你遗漏了一个重要的位 - 一个布尔标志,允许它引发事件

bgwDataWorker.WorkerReportsProgress = true;
bgwDataWorker.WorkerSupportsCancellation = true;

答案 5 :(得分:0)

我有一个项目[A],(建立了一段时间),进度条工作。当前应用[B]未报告进度。出于某种原因app [A]有进度和工作完成事件处理程序连线。所以,我在app [B]中连接了事件处理程序,它正在运行。处理程序将复制到designer.cs分部类文件中。 (假设他们可以进入form.cs分​​部课)。

// 
        // backgroundWorker1
        // 
        this.backgroundWorker1.WorkerReportsProgress = true;
        this.backgroundWorker1.WorkerSupportsCancellation = true;
        this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
        this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
        this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
//
希望这会有所帮助。不知道为什么应用程序[A]通过使用工具箱在表单设计窗口中删除后台工作程序来连接。使用VS2012和Windows 7。

另外,我正在计算进度百分比,并且由于某种原因,列表框中项目的数量超过了所选复选框的数量超过100% - 它投掷和错误。因此,我将百分比限制在99,并将我的逻辑部分用于报告回事件的进度百分比。

答案 6 :(得分:0)

我最近遇到过这个问题。之所以这是因为我让主线程一直处于休眠状态,直到后台线程完成,这阻止了更新的执行。

我通过将对象(包含工作线程)包装到另一个线程中解决了这个问题,因此可以执行进度更新,更改主线程中的值,允许我的休眠线程继续。