![](/img/trans.png)
[英]C# Service worker start an application as background process, how to start the app in normal state?
[英]C# Before closing application how to let background worker finish saving application state
在C#桌面应用程序中,在2种情况下将调用负责保存应用程序状态的后台工作人员。 在应用程序运行时一次。 很好 其他情况是在关闭应用程序时,调用backgroundworker来保存应用程序状态,但是在开始保存之前,该应用程序已关闭并且什么也没有保存。
我试图通过在DoWork和RunWorkerCompleted中使用AutoReset事件类来解决此问题,但由于在backgroundworker可以保存任何内容之前应用程序已关闭,因此无法正常工作。
问题是-如何让主线程等到后台工作者完成保存?
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();
}
是WinForms吗?
也许您可以注册OnClosing事件。 在其中,将私有属性IsClosing设置为true。 将事件处理程序e标记为e.Handled = true。
注册到BackgroundWorker事件RunWorkerCompleted。 在其中,检查是否设置了IsClosing属性,在这种情况下,请检查MainForm.Close()应用程序。
编辑:
using System;
using System.Threading;
using System.Windows.Forms;
using System.ComponentModel;
namespace BgWorker
{
public partial class Form1 : Form
{
BackgroundWorker _bgWorker;
bool _iNeedToCloseAfterBgWorker;
public Form1()
{
InitializeComponent();
}
void Form1_Load(object sender, EventArgs e)
{
_bgWorker = new BackgroundWorker();
_bgWorker.DoWork += _bgWorker_DoWork;
_bgWorker.RunWorkerCompleted += _bgWorker_RunWorkerCompleted;
}
void _bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Done!");
if (_iNeedToCloseAfterBgWorker)
Close();
}
void _bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Do long lasting work
Thread.Sleep(2000);
}
void btnWorkIt_Click(object sender, EventArgs e)
{
// Note how the Form remains accessible
_bgWorker.RunWorkerAsync();
}
void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (_iNeedToCloseAfterBgWorker || _bgWorker.IsBusy) return;
e.Cancel = true;
_iNeedToCloseAfterBgWorker = true;
_bgWorker.RunWorkerAsync();
}
}
}
将SaveState代码放在单独的方法中会更清洁,该方法从后台工作程序调用,并且在关闭应用程序时(同步)调用。
要么,要么您可以基于手动重置事件(ManualResetEvent-class)阻止应用程序关闭。
只是提出一个想法。 MainForm上的一个可变的DateTime属性。 (注意-DateTimes不能随便出现,因此可以使用字符串表示形式)
public volatile string _lastUpdated;
每次在后台工作线程上执行save事件时,都会更新此属性。
OnClose将检查DateTime.Now与存储的日期时间之间的时差。
例如:
var timeDiff = DateTime.Now - _lastSavedTime;
如果OnClose检测到timeDiff.TotalSeconds <30(少于30秒),则可以在完成close事件之前从主线程手动触发save事件。
但是,这不能防范Process.Kill-很少有人可以防范。 我只能建议您以一种明智的方式管理您的储蓄。 例如:每次保存到一个新文件,保留最后5次保存。 进行第六次保存后,删除最早的保存等
这是为了解决Process.Kill方案中可能发生的潜在损坏。 意味着如果30秒备份失败,您至少还有60秒的备份时间。
我对这个问题的解决方案是等到backgroundworker异步调用之后添加以下内容,直到backgroundworker完成。
while (this.backgroundWorkerMain1.IsBusy)
{
Application.DoEvents();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.