同时与计时器和后台工作人员一起工作
本文关键字:工作人员 一起 工作 后台 计时器 | 更新日期: 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();
}
}
希望这能帮助到你。