C# Windows进程可以';不要关闭我的申请

C# Windows进程可以';不要关闭我的申请,c#,winforms,process,task,shutdown,C#,Winforms,Process,Task,Shutdown,我有一个windows窗体应用程序,它正在数据库中写入大量内容。前一段时间,我在问如何确保在关闭windows窗体之前完成所有请求(写入数据库) 我这样做的原因是因为它将是一个自动关闭的独立应用程序,因此我需要能够完成数据库中的所有写入和读取,并确保在关闭表单时所有工作都已完成 在尝试此解决方案之前,由于表单关闭,我在数据库中写入时遇到了断开连接的问题 现在的问题是,当我有一个关闭进程时,我的windows窗体应用程序不会关闭,所以一段时间后,它只是切断了我不需要的电力 这是密码,请告诉我有什么

我有一个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进入关机阶段时,它就不起作用了。有什么想法吗?也许我需要更改其他事件,而不是表单关闭?还有一件事。我已将应用程序进程的优先级保存为实时进程。

如果您的进程花费的时间超过几秒钟,操作系统将在关机时终止它。您唯一的希望是中止关机,完成工作,然后再次调用它

您的进程只需要几秒钟,并且依赖于表单的实例,因此此解决方案不会创建新线程来执行工作。因此,您应该
隐藏
表单以防止使用交互,因为在运行此进程时,主线程将被锁定

如果关闭事件试图关闭应用程序。应用程序将中止关机。不过,它需要
管理员
权限才能执行此操作

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();
        }
    }
}

使用参数
-a
调用
shutdown.exe
不是更好吗?这样可以有效地中止,然后您可以在准备就绪时调用shutdown。所以问题是当Windows关闭时不会触发FormClosing事件?代码段中有大量不必要的代码。使用任务然后等待它没有意义,运行shutdown.exe没有意义。DBUpdate()需要多长时间?如果超过几秒钟,你就无法让它工作。嗯,我不知道实际需要多少时间。但我认为这几秒钟就足够完成这个请求了。当我编辑我的问题时,当我点击X按钮关闭窗体事件被触发,但我不能检查它是否触发当我重新启动它。我已经尝试了你的代码,它只是切断我在更新的中间,我得到错误窗口。在我在问题中写的第一个程序中,它等待的时间太长了,现在它不等待了。我需要确保所有东西都正确保存。我刚刚检查过。当我点击X按钮,然后程序进入DbUpdate(),我有一些空异常,因为它没有等待。我在这里得到了它的工作,我需要更多关于错误消息的详细信息,您正在得到解决问题。您是否以管理员身份运行应用程序?因此不喜欢在评论中进行长时间的对话。如果你想在c#聊天室见我,我们就调试解决方案。经过一段时间的尝试,我可以忍受这个关闭错误:)我不知道是否所有的事情都正确完成并保存了,但程序正在关闭:)有什么东西可以删除shutdown.exe窗口吗?