C#在关闭应用程序之前,如何让后台工作人员完成保存应用程序状态
在C#桌面应用程序中,负责保存应用程序状态的backgroundworker在两种情况下被调用。在应用程序运行时执行一次。那很好。另一种情况是,在关闭应用程序时,会调用backgroundworker来保存应用程序状态,但在开始保存之前,应用程序将关闭,并且不会保存任何内容 我试图通过在DoWork和RunWorkerCompleted中使用AutoReset事件类来解决这个问题,但没有成功,因为应用程序在backgroundworker可以保存任何东西之前关闭了 问题是-如何让主线程等待backgroundworker完成保存C#在关闭应用程序之前,如何让后台工作人员完成保存应用程序状态,c#,multithreading,winforms,C#,Multithreading,Winforms,在C#桌面应用程序中,负责保存应用程序状态的backgroundworker在两种情况下被调用。在应用程序运行时执行一次。那很好。另一种情况是,在关闭应用程序时,会调用backgroundworker来保存应用程序状态,但在开始保存之前,应用程序将关闭,并且不会保存任何内容 我试图通过在DoWork和RunWorkerCompleted中使用AutoReset事件类来解决这个问题,但没有成功,因为应用程序在backgroundworker可以保存任何东西之前关闭了 问题是-如何让主线程等待bac
private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
this.saveAHToolStripMenuItem_Click(this, e);
}
private void saveAHAsToolStripMenuItem_Click(object sender, EventArgs e)
{
this.backgroundWorkerMain1.RunWorkerAsync(args);
}
private void backgroundWorkerMain1_DoWork(object sender, DoWorkEventArgs e)
{
saveMethod();
}
private void backgroundWorkerMain1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
showResultOfSaving();
}
将SaveState代码放在一个单独的方法中会更干净,该方法在后台工作程序中调用,并在关闭应用程序时(同步)调用 或者,您可以基于手动重置事件(ManualResetEvent类)阻止应用程序关闭。是WinForms吗 也许你可以注册参加一次失败的活动。 在其中,将私有属性IsClosing设置为true。 将eventhandler e标记为e.Handled=true 注册到BackgroundWorker事件RunWorkerCompleted。在其中,检查是否设置了IsClosing属性,在这种情况下,检查MainForm.Close()应用程序 编辑:
只是在那里抛出一个想法。 可能是主窗体上的一个不稳定的DateTime属性。 (注意-DateTimes在出现时不能是易变的,因此可以使用字符串表示) 每次在后台工作线程上执行保存事件时,都会更新此属性 OnClose将检查DateTime.Now与存储的日期时间之间的时差 例如: 如果OnClose检测到timeDiff.TotalSeconds<30(小于30秒) 然后,在关闭事件完成之前,可以从主线程手动触发保存事件 然而,这并不能防止进程的破坏。杀戮——几乎没有什么可以防止这种破坏。 我所能建议的是,你要以一种明智的方式管理你的储蓄。 每次保存到新文件,保留最后5次保存。 第六次保存时,删除最早的保存等
这是为了说明Process.Kill场景中可能发生的潜在损坏。意味着您仍将有至少60秒的备份,以防30秒的备份失败。我解决此问题的方法是在backgroundworker异步调用后添加以下命令,直到backgroundworker完成
while (this.backgroundWorkerMain1.IsBusy)
{
Application.DoEvents();
}
在该事件被触发之前不要关闭:如果您展示了您的一些工作,我们可以提供更多帮助。谢谢您的参考。我已经用基本的代码结构更新了我的问题。在这里,FormClosing在backgroundWorker完成保存之前完成。您好,我在下面的回答中添加了编辑解决方案。我将检查ManualResetEvent是否可以在主线程内部使用而不阻塞它。您的第一个同步建议似乎类似于Baaleos建议将其保存在主关闭方法中。好的,我检查了ManualResetEvent,当我在主线程中调用WaitOne()时,应用程序被挂起,当在DoWork()中调用它时,应用程序在保存之前被关闭。是的,在关闭时,我还考虑将其单独保存在主线程中,但backgroundworker正在保存例程中作为参数传递。我想它可能会被重复的代码弄得很复杂。在保存之前,我要求用户保存或不保存,所以我不需要检查时差。是的,它是WinForms。我不能接受你的建议。在FormClosing()中继续运行后面的语句之前,它将如何启用DoWork()运行?您好,我添加了解决方案,因为EditSolution已共享。如果后台工作人员很忙,我不想返回,但想一直等到它完成。@Saad“解决方案已经共享”是什么意思?如果它对你有帮助,请标记为答案。此外,如果bgWorker正忙,那么返回主线程正是您所需要的。
public volatile string _lastUpdated;
var timeDiff = DateTime.Now - _lastSavedTime;
while (this.backgroundWorkerMain1.IsBusy)
{
Application.DoEvents();
}