c# - 为什么我的程序在取消BackgroundWorker后执行?

标签 c# wpf backgroundworker

我正在练习使用BackgroundWorker来做一些耗时的工作。 我的目标是在 UI 上显示所有文件路径。

enter image description here

我按RUN按钮,执行5秒后按CANCEL按钮。效果很好。

然后我重复上述步骤,我注意到“Check_File”被第三次执行。

我认为应该只有两次。

用户界面如下所示:

  1. Searching for Files → Many FileName Appear → Canceled

  2. 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/

相关文章:

c# - 反编译 C# .Net 1.1 应用程序的最佳工具

c# - 请求类型为“System.Data.Odbc.OdbcPermission..”的权限需要帮助

c# - 如何用等效的符号替换网页代码?

wpf - 获取 MainWindow 的位置/宽度/高度

c# - Serilog 不会将日志输出到 txt 文件中

c# - 鼠标滚动事件

c# - 如何使 WPF Combobox 的下拉列表保持打开和放置

c# - WpfAnimatedGif 不要停留在特定的框架中

c# - BackgroundWorker 意外死亡