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

プロセスに数秒以上かかる場合、OS はシャットダウン中にプロセスを強制終了します。あなたの唯一の希望は、シャットダウンを中止し、作業を行い、再度呼び出すことです。

あなたのプロセスは数秒しかかからず、フォームのインスタンスに依存しているため、このソリューションは作業を行うための新しいスレッドを作成しません。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 に答える