我有一个Windows表单应用程序,它在数据库中编写一堆东西。现在前一段时间我一直在寻求解决方法,以确保在窗体关闭之前所有请求(写入数据库)都已完成。
我这样做的原因是因为它将是一个自动关闭的应用程序,因此我需要能够完成所有写入和从数据库中读取并确保何时关闭表单所有工作都已完成。
在尝试此解决方案之前,由于表单关闭,我在写入数据库时遇到了切断连接的问题。
现在的问题是,当我关闭进程时,我的Windows窗体应用程序将无法关闭,所以一段时间之后它只是切断了我不需要的电力。
这是代码,请告诉我它有什么问题?当程序确定没有任务在后台运行时,我需要关闭表单。
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// this.Visible = false; // optional
// this.ShowInTaskbar = false; // optional
Task db = Task.Factory.StartNew(() => DBUpdate());
Task.WaitAll(db);
if (this.shutdownRequested)
Process.Start("shutdown.exe", "-s");
}
protected override void WndProc(ref Message ex)
{
if (ex.Msg == WM_QUERYENDSESSION)
{
Message MyMsg = new Message() { Msg = WM_CANCELMODE };
base.WndProc(ref MyMsg);
this.shutdownRequested = true;
} else {
base.WndProc(ref ex);
}
}
编辑:
我刚刚意识到当我单击 X 按钮并且表单开始关闭时,这是有效的,但是当pc进入关闭阶段时则不然。任何的想法?也许我需要更改其他内容的事件,而不是 FormClosing ?还有一件事。我已将申请流程的优先级保存为实时流程。
答案 0 :(得分:1)
如果您的过程需要几秒钟,操作系统将在关机期间将其终止。你唯一的希望是中止关机,完成工作并再次打电话。
您的进程只需要几秒钟,并且依赖于Form的实例,因此此解决方案不会创建新的线程来完成工作。所以您应该hide
表单防止使用交互,因为在运行此进程时主线程将被锁定。
如果关闭事件尝试关闭应用程序。该应用程序将中止关闭。但是,它需要administrator
个权限才能执行此操作。
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
using Timer = System.Windows.Forms.Timer;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private bool _isClosing;
private bool _isRunningUpdate;
private bool _isShutdown;
private Timer timer;
public Form1()
{
InitializeComponent();
FormClosing += Form1_FormClosing;
timer = new Timer();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.WindowsShutDown)
{
// Abort Shutdown
Process.Start("shutdown.exe", "-a");
_isShutdown = true;
}
if (!_isRunningUpdate && _isClosing) return;
// Set isClosing to true
_isClosing = true;
if (!_isRunningUpdate)
{
_isRunningUpdate = true;
timer.Tick += DbUpdate;
timer.Interval = 500;
timer.Enabled = true;
timer.Start();
}
// Cancel current close request
e.Cancel = true;
// Optional Hide() --- could display message
// Hide();
}
private void DbUpdate(object sender, EventArgs e)
{
timer.Stop();
Thread.Sleep(3000);
_isRunningUpdate = false;
if (_isShutdown)
Process.Start("shutdown.exe", "-s -t 10");
if (_isClosing)
Close();
}
}
}