0

我有一个 Windows 窗体应用程序,它正在数据库中写入一堆东西。现在前段时间我在询问如何确保在关闭 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?还有一件事。我已将应用程序进程的优先级保存为实时进程。

4

1 回答 1

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();
        }
    }
}
于 2012-09-02T12:24:54.747 回答