为什么取消BackgroundWorker后我的程序就执行了?
Why my program executed after I cancel BackgroundWorker?
正在练习使用BackgroundWorker做一些比较耗时的工作。
我的目标是显示 UI.
上的所有文件路径
我按运行键,执行5秒后按取消键。它工作正常。
然后我重复上面的步骤,我注意到"Check_File"第三次执行了。
我觉得应该只有两次。
UI 显示如下:
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 在评论中提到的,您还可以在附加新事件之前删除现有事件。
正在练习使用BackgroundWorker做一些比较耗时的工作。 我的目标是显示 UI.
上的所有文件路径我按运行键,执行5秒后按取消键。它工作正常。
然后我重复上面的步骤,我注意到"Check_File"第三次执行了。
我觉得应该只有两次。
UI 显示如下:
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 在评论中提到的,您还可以在附加新事件之前删除现有事件。