【问题标题】:Be sure C# code executes before shutdown [closed]确保 C# 代码在关机前执行 [关闭]
【发布时间】:2017-07-12 06:26:08
【问题描述】:

我正在开发一个需要节省计算机关闭时间的应用程序,我需要确保始终计算机关闭/重新启动,此代码执行。

我在表单关闭事件中这样写:

    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {         
        if(e.CloseReason == CloseReason.WindowsShutDown)
        {
            Properties.Settings.Default.lastShutdown = DateTime.Now;
            Properties.Settings.Default.Save();
        }
    }

通常代码正在运行,它会在设置中保存 DateTime,但我认为有时应用程序在保存完成之前关闭并丢失数据。我不知道应用程序在关闭时关闭之前还有多少时间。

¿有什么方法可以确保代码总是在关机前完成?

谢谢。

【问题讨论】:

  • “我认为有时应用程序可以在保存完成之前关闭并丢失数据” - 这总是有可能的。如果您的代码效率低下或速度慢,则几率会增加,因为 Windows 可能会终止它。但是用户总是可以直接杀死你的程序,或者电源可能会熄灭,或者其他什么。你需要能够优雅地从这些情况中恢复过来。
  • 另外提供的代码有很多情况下它永远不会运行。因此,如果有人只是因为他想要您而关闭您的表格,则不会节省时间。如果您可以在内部捕获 windows 消息,为什么还要费心等待 form_closure 呢?
  • 除了已经提到的事实之外,没有任何东西可以让您的代码知道何时将发生电源故障,windows事件系统已经尽力记录关机和启动事件。为什么要复制该功能而不仅仅是查询事件日志?
  • @Damien_The_Unbeliever 这是个好主意,我将尝试查询 Windows 事件日志而不是保存它。你知道如何阅读它的例子吗?谢谢。

标签: c# .net winforms


【解决方案1】:

您可以将处理程序附加到SystemEvents.SessionEnded 事件并在那里运行您的代码。您甚至可以使用 Cancel 属性取消关闭/注销事件。 相同的代码可以在FormClosing 事件上运行,但CloseReason == CloseReason.UserClosing || CloseReason == CloseReason.ApplicationExitCall || CloseReason == CloseReason.TaskManagerClosing 可以覆盖所有场景。

【讨论】:

    【解决方案2】:

    您可以定期保存每个会话的最后一次存活时间。例如在表单上创建一个计时器。这样,即使您立即断电,您也可以知道上一次活着是什么时候。

    private void Form1_Load(object sender, EventArgs e)
    {
        /* Set the last shutdown to the last time we were alive.. */
        Properties.Settings.Default.LastShutdown = Properties.Settings.Default.LastHeartbeat;
    
        this.timer1.Interval = 100;
        this.timer1.Tick += timer1_Tick;
        this.timer1.Start();
    
    }
    
    private void timer1_Tick(object sender, EventArgs e)
    {
        Properties.Settings.Default.LastHeartbeat = DateTime.UtcNow;
        Properties.Settings.Default.Save();
    }
    

    【讨论】:

      【解决方案3】:

      我认为如果你定期保存变量会更好,而不是节省“喊停时间”。这样,如果出现问题,您最多会失去 1 个间隔。

      【讨论】:

        【解决方案4】:

        只需使用计时器保存整个时间,当计算机关闭并重新启动时,您调用配置中的最后一个条目。

        `Timer time = new Timer(1);
        time.Elapsed += timer_elapsed();
        private static void timer_elapsed(Object source, System.Timers.ElapsedEventArgs e) { YOUR CODE HERE}`
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-03-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多