gpt4 book ai didi

c# - 为什么我不能使 BackgroundWorker() 按预期工作?

转载 作者:行者123 更新时间:2023-12-05 04:24:12 24 4
gpt4 key购买 nike

我正在尝试运行以下代码来测试 BackgroundWorker,但这给我带来了很多问题:

using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace BackgroundWorkingTest
{
public partial class Form1 : Form
{
BackgroundWorker backgroundWorker1 = new BackgroundWorker();
int counter;

public Form1()
{
InitializeComponent();

backgroundWorker1 = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};

backgroundWorker1.DoWork += BackgroundWorker1_DoWork;
backgroundWorker1.ProgressChanged += BackgroundWorker1_ProgressChanged;
backgroundWorker1.RunWorkerCompleted += BackgroundWorker1_RunWorkerCompleted;
}

private void StartButton_Click(object sender, EventArgs e) // Start
{
counter = 0;
backgroundWorker1.RunWorkerAsync();
}

private void CancelButton_Click(object sender, EventArgs e) // Cancel
{
backgroundWorker1.CancelAsync();
progressLabel.Text = "0";
}

private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e) // DoWork
{
int i;

for (i = 0; i < 123456; i++)
{
// Application.DoEvents(); // This line doesn't help
// Thread.Sleep(1); // Enable this line solve the problem

backgroundWorker1.ReportProgress(i + 1);
counter++;

if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}
}
}

private void BackgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) // Progress
{
progressLabel.Text = counter.ToString();
progressLabel.Refresh();
}

private void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) // Completed
{
if (e.Cancelled)
MessageBox.Show("Operation Cancelled");
else
MessageBox.Show("Operation Completed");
}
}
}

1. 例如,在 BackgroundWorker1_DoWork() 方法中您可以看到命令:

Thread.Sleep(1);

如果我禁用它,则“取消”按钮没有响应。我点击它几次,但它没有停止进程,我也没有收到“操作已取消”消息。

如果我启用它,它就会工作,但我不想在我的线程中使用任何 Sleep(1) 命令,因为它只会减慢进程,我不希望这样。

如果我启用命令:

Application.DoEvents();

它根本没有帮助,“取消”按钮在计数过程中也没有响应。

2. 我看到的另一个问题是,如果我使用命令:

progressLabel.Refresh();

在 ProgressChanged() 事件中,发生了一些非常奇怪的事情。我可以在面板上看到它已完成计数,并在标签上显示:“123456”。但是 之后 花了将近一分钟才显示“操作已完成”消息。

如果在标签显示“123456”后,我在 ProgressChanged() 方法中设置了一个断点,然后我看到它一直进入 e.ProgressPercentage 参数一直上升的方法。

怎么可能呢?如果我在面板上看到“123456”,它不是说进程已经完成了吗?如果是,那它为什么不立即向我显示“操作已完成”消息?

3. 如果我删除“progressLabel.Refresh()”行,那么我会在标签显示“123456”后立即收到“操作已完成”消息,但随后却没有t 显示 0 到 123456 之间的计数(正如我在启用 Refresh() 命令时看到的那样)。

4. 还有一点我不太明白:

当我更改代码以使用多个 BackgroundWorker 的数组而不是一个时:

BackgroundWorker[] backgroundWorker1 = new ....

启用 Sleep(1) 后,我没有收到任何错误消息,尽管所有线程都将文本设置为相同的标签,并将值写入相同的计数器。

有意义吗?从多个 BackgroundWorker 线程同时更新同一标签时,我怎么没有收到任何运行时错误?

非常感谢。

最佳答案

您过于频繁地报告进度:

for (i = 0; i < 123456; i++)
{
backgroundWorker1.ReportProgress(i + 1);

...并且窗口的消息循环被消息溢出。因此它无法及时处理 CancelButton_Click 事件。

关于c# - 为什么我不能使 BackgroundWorker() 按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73561953/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com