同时与计时器和后台工作人员一起工作

本文关键字:工作人员 一起 工作 后台 计时器 | 更新日期: 2023-09-27 18:27:02

我想在计时器滴答事件中调用一个函数,以便它执行到计时器间隔结束。问题是该函数正在与后台工作程序一起工作,我无法设置e。Cancel=true可在时间结束前停止函数执行。这是我试过的。

private void timer1_Tick_1(object sender, EventArgs e)
{
    presenter.RunEngine();    // call the function here
    // ...
}
-------------------------------------------------------
public BackgroundWorker worker;
public PresenterClass()
{
   worker = new BackgroundWorker();
   worker.DoWork += new DoWorkEventHandler(Worker_DoWork);
   worker.ProgressChanged += new ProgressChangedEventHandler(Worker_ProgressChanged);
   worker.WorkerReportsProgress = true;
   worker.WorkerSupportsCancellation = true;
}
private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
   DisplayState();
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
   if (worker.CancellationPending)
   {
      e.Cancel = true;
      worker.ReportProgress(0);
      return;
   }
   worker.RunWorkerAsync();  // I don't think I should call it here, but it doesn't work otherwise
}
public void RunEngine()
{
   if (worker.CancellationPending)
   {
      view.timer.Enabled = false;
      view.timer.Stop();
      // here I should be able to set e.Cancel = true;
      return;
   }
   double oxygenLevel = _systemEngine.Subsystems.Where(s => s.Article == "Oxygen").First().State.Level;
   if (oxygenLevel > 0)
   {
      ConsumeEngine();
   }
   else
   {
      worker.CancelAsync();
   }
}
private void ConsumeEngine()
{
   Parallel.ForEach(_systemEngine.Subsystems, (currentSystem) =>
   {
      if (currentSystem is ShieldMatrix)
      {
         ConsumeShields(currentSystem);
      }
      else if (currentSystem is WeaponToolbar)
      {
         ConsumeWeapons(currentSystem);
      }
      else {
         currentSystem.State.Consume();
      }
    ));
    worker.ReportProgress(90);
    }
private void ConsumeWeapons(BaseModel currentSystem)
{
   // ...
}
private void ConsumeShields(BaseModel currentSystem)
{
   // ...
}

同时与计时器和后台工作人员一起工作

我同意其他人的意见,他们认为有更好的方法可以实现这一功能,但如果你仍然要继续使用这种方法,那么你需要让DoWorkEventArgs以某种方式可供RunEngine方法访问。例如,在调用RunWorkerSync方法之前,您可以声明一个实例字段来存储后台工作程序的参数。

    //Declare an instance to store the arguments of the background worker
    public DoWorkEventArgs DoWorkEventArgsIntance { get; set; }

private void Worker_DoWork(object sender, DoWorkEventArgs e)
    {
        if (worker.CancellationPending)
        {
            e.Cancel = true;
            worker.ReportProgress(0);
            //Clear the DoWorkEventArgs intance
            DoWorkEventArgsIntance = null;
            return;
        }
        //Set the instance to the current value of the bw
        DoWorkEventArgsIntance = e;
        worker.RunWorkerAsync(); // I don't think I should call it here, but it doesn't work otherwise
    }

然后在RunEngine方法上,当您需要停止执行时,您可以访问参数,并且可以调用Cancel。

public void RunEngine()
    {
        if (worker.CancellationPending)
        {
            view.timer.Enabled = false;
            view.timer.Stop();
            // here I should be able to set e.Cancel = true;
            //As we stored the value before start the worker, now we can cancel here
            DoWorkEventArgsIntance.Cancel = true;
            return;
        }
        double oxygenLevel = _systemEngine.Subsystems.First(s => s.Article == "Oxygen").State.Level;
        if (oxygenLevel > 0)
        {
            ConsumeEngine();
        }
        else
        {
            worker.CancelAsync();
        }
    }

希望这能帮助到你。