使用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事件由于某种原因根本没有被提出,我不明白为什么。
感谢阅读。
艾伦
答案 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)
我最近遇到过这个问题。之所以这是因为我让主线程一直处于休眠状态,直到后台线程完成,这阻止了更新的执行。
我通过将对象(包含工作线程)包装到另一个线程中解决了这个问题,因此可以执行进度更新,更改主线程中的值,允许我的休眠线程继续。