我正在练习使用BackgroundWorker来做一些耗时的工作。 我的目标是在 UI 上显示所有文件路径。
我按RUN按钮,执行5秒后按CANCEL按钮。效果很好。
然后我重复上述步骤,我注意到“Check_File”被第三次执行。
我认为应该只有两次。
用户界面如下所示:
Searching for Files → Many FileName Appear → Canceled
Searching for Files → Many FileName Appear → Searching for Files → Canceled
以下是我的代码:
private void Run_Click(object sender, RoutedEventArgs e)
{
worker.WorkerSupportsCancellation = true;
worker.WorkerReportsProgress = true;
worker.DoWork += Worker_DoWork;
worker.ProgressChanged += Worker_ProgressChanged;
worker.RunWorkerAsync(PText.Text);
worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
FLabel.Content = "Canceled";
}
else
{
FLabel.Content = "Finish";
}
worker.Dispose();
}
private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
FLabel.Content = e.UserState.ToString();
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
Check_File("My_Folder_Path", (String)e.Argument, e);
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
worker.CancelAsync();
}
public void Check_File(string Path, string FindStr, DoWorkEventArgs e)
{
string v_alert;
i += 1;
try
{
if (Path.LastIndexOf('\\') != Path.Length)
{
Path = string.Concat(Path, "\\");
}
if (Directory.Exists(Path))
{
worker.ReportProgress(0, string.Concat("Searching for Files...", i.ToString()));
string[] Files = Directory.GetFiles(Path);
if (Files.Length != 0)
{
foreach (string f in Files)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
worker.ReportProgress(Array.IndexOf(Files, f) / Files.Length * 100, f);
}
}
}
else
{
v_alert = string.Concat("No Path:", Path);
MessageBox.Show(v_alert);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
最佳答案
每次按下按钮时,都会向工作人员添加一个事件。
private void Run_Click(object sender, RoutedEventArgs e)
{
worker.WorkerSupportsCancellation = true;
worker.WorkerReportsProgress = true;
worker.DoWork += Worker_DoWork; //<----Happens here
worker.ProgressChanged += Worker_ProgressChanged;
worker.RunWorkerAsync(PText.Text);
worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
}
所以如果你按一次。该工作人员附加了一个事件。如果您第二次按下它,工作人员会附加另一个事件。他现在有两个事件。他又跑了一次(这次有 2 个项目),总共跑了 3 次。
您应该在其他地方设置工作人员。
public Form1()
{
InitializeComponent();
//Init the worker here...
worker.WorkerSupportsCancellation = true;
worker.WorkerReportsProgress = true;
worker.DoWork += Worker_DoWork;
worker.ProgressChanged += Worker_ProgressChanged;
worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
}
private void Run_Click(object sender, RoutedEventArgs e)
{
//only run the worker here
worker.RunWorkerAsync(PText.Text);
}
正如 Shocky 在评论中提到的,您还可以在附加新事件之前删除现有事件。
关于c# - 为什么我的程序在取消BackgroundWorker后执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60315061/