0

最小化されたフォーム アプリケーションを右クリックして閉じるか、タスク マネージャー アプリケーション タブを使用してプロセスを終了しようとすると、タイマーが定義され、実行中または有効になっている間、FormClosing イベントがトリガーされません。

//Extract from Form designer.cs:
....
private System.Windows.Forms.Timer timer1;
....
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.timer1.Interval = 5000;
....
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
......
this.Load += new System.EventHandler(this.FormSI_Load);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormSI_FormClosing);


//Extract from form.cs:
namespace namespace
{
    public partial class FormSI : Form
    {
       .....
       public FormSaturnInterface()
       {
          InitializeComponent();
          ......
          timer1.Interval = intTimerIntervalms;
          //timer1.Enabled = true; //FormClosing event not triggered if timer1 enabled
          timer1.Enabled = false;  //FormClosing event triggered if timer1 not enabled
          ........
          private void FormSI_Load(object sender, EventArgs e)
          {
                  MessageBox.Show("Load Event triggered["+ e.ToString() + "]", "Load Event triggered", MessageBoxButtons.OK); //Load event always triggered with or without timer1 enabled
          }

          private void FormSI_FormClosing(Object sender, FormClosingEventArgs e)
          {
               //e.Cancel = true; //stops app/form closing
              timer1.Stop();
              System.Text.StringBuilder messageBoxCS = new System.Text.StringBuilder();
              messageBoxCS.AppendFormat("{0} = {1}", "CloseReason", e.CloseReason);
              messageBoxCS.AppendLine();
              messageBoxCS.AppendFormat("{0} = {1}", "Cancel", e.Cancel);
              messageBoxCS.AppendLine();
              MessageBox.Show(messageBoxCS.ToString(), "FormClosing Event");
          }
          ........

アプリケーションを閉じる/終了する試みが行われるまでタイマーを停止/無効にしたくありませんが、それでもフォームクロージングイベントをトリガーしたいと考えています。このシナリオの可能な解決策は何ですか? どんな援助でも大歓迎です。

FormSI.designer.cs には既に次のコードが含まれていることに注意してください。

/// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        MessageBox.Show("Disposing", "Disposing", MessageBoxButtons.OK);

        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

この Dispose メソッドは、timer1 が無効になっているときに Form_FormClosing イベントと同じように呼び出されますが、timer1 が有効になっているときにどちらも呼び出されないように見えます。この場合、終了タスクがアプリ/フォームを終了する唯一の方法です。Close 要求を処理する時間がなく、スレッドがビジー状態である可能性はありますか? もしそうなら、どのようにしてスレッドを定期的に中断させて、クローズ要求を処理できるようにすることができますか?

問題は、アプリを正常に閉じることができず、ユーザーがたとえばデータを保存するように求められたり、本当にアプリを閉じるつもりだったのかということでした。この問題は、特定のデータベースが利用できず、単一のスレッドで他のメッセージ/イベントを処理できない場合にタイマーがループに陥ることに関係していました。タイマーがループを終了するとすぐに、タイムアウトするか、必要なデータベースに到達することにより、キューに入れられたすべてのメッセージ/イベントが正しく処理されました。時間とフィードバックをくれたすべての回答者に感謝します. :)

4

1 に答える 1

0

この問題は、特定のデータベースが利用できず、単一のスレッドで他のメッセージ/イベントを処理できない場合にタイマーがループに陥ることに関係していました。タイマーがループを終了するとすぐに、タイムアウトするか、必要なデータベースに到達することにより、キューに入れられたすべてのメッセージ/イベントが正しく処理されました。時間とフィードバックをくれたすべての回答者に感謝します. :)

于 2014-01-10T13:08:14.957 に答える