检测 PowerModeChange 并等待执行
Detect PowerModeChange and wait for execution
我想运行在计算机挂起时保存一些例程。因此,我使用 OnPowerChange-Event 来检测它何时暂停和恢复。不幸的是,我的保存例程需要 3-5 秒才能执行。
当我收到挂起事件时,计算机会在 1-2 秒内关闭并且我的例程没有完全执行。
如何在例程完成之前防止挂起?
SystemEvents.PowerModeChanged += OnPowerChange;
private void OnPowerChange(object s, PowerModeChangedEventArgs e)
{
switch (e.Mode)
{
case PowerModes.Resume:
switchEdifier(true);
break;
case PowerModes.Suspend:
switchEdifier(false);
break;
}
}
有一些非托管 API 可以帮助解决这个问题,特别是 ShutdownBlockReasonCreate and ShutdownBlockReasonDestroy。
需要注意的是,这两个函数必须配对,当你调用一个时,你必须确保你调用了另一个(例如,如果一个例外),否则关闭可能会被无限期地阻止。
这将导致出现一个对话框,告诉用户哪些程序正在阻止关机,以及阻止关机的原因。快速完成工作并离开很重要,因为用户可以选择点击他们经常使用的 "Force Shutdown" 按钮。
这是一个使用它的例子:
[DllImport("user32.dll", SetLastError=true)]
static extern bool ShutdownBlockReasonCreate(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] string reason);
[DllImport("user32.dll", SetLastError=true)]
static extern bool ShutdownBlockReasonDestroy(IntPtr hWnd);
//The following needs to go in a Form class, as it requires a valid window handle
public void BlockShutdownAndSave()
{
//If calling this from an event, you may need to invoke on the main form
//because calling this from a thread that is not the owner of the Handle
//will cause an "Access Denied" error.
try
{
ShutdownBlockReasonCreate(this.Handle, "You need to be patient.");
//Do your saving here.
}
finally
{
ShutdownBlockReasonDestroy(this.Handle);
}
}
鼓励使用简短的原因字符串,因为用户通常不会阅读长消息。吸引注意力的东西,例如 "Saving data" 或 "Flushing changes to disk"。请注意 "do it anyway I'm an impatient user" 按钮。
我想运行在计算机挂起时保存一些例程。因此,我使用 OnPowerChange-Event 来检测它何时暂停和恢复。不幸的是,我的保存例程需要 3-5 秒才能执行。
当我收到挂起事件时,计算机会在 1-2 秒内关闭并且我的例程没有完全执行。
如何在例程完成之前防止挂起?
SystemEvents.PowerModeChanged += OnPowerChange;
private void OnPowerChange(object s, PowerModeChangedEventArgs e)
{
switch (e.Mode)
{
case PowerModes.Resume:
switchEdifier(true);
break;
case PowerModes.Suspend:
switchEdifier(false);
break;
}
}
有一些非托管 API 可以帮助解决这个问题,特别是 ShutdownBlockReasonCreate and ShutdownBlockReasonDestroy。
需要注意的是,这两个函数必须配对,当你调用一个时,你必须确保你调用了另一个(例如,如果一个例外),否则关闭可能会被无限期地阻止。
这将导致出现一个对话框,告诉用户哪些程序正在阻止关机,以及阻止关机的原因。快速完成工作并离开很重要,因为用户可以选择点击他们经常使用的 "Force Shutdown" 按钮。
这是一个使用它的例子:
[DllImport("user32.dll", SetLastError=true)]
static extern bool ShutdownBlockReasonCreate(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] string reason);
[DllImport("user32.dll", SetLastError=true)]
static extern bool ShutdownBlockReasonDestroy(IntPtr hWnd);
//The following needs to go in a Form class, as it requires a valid window handle
public void BlockShutdownAndSave()
{
//If calling this from an event, you may need to invoke on the main form
//because calling this from a thread that is not the owner of the Handle
//will cause an "Access Denied" error.
try
{
ShutdownBlockReasonCreate(this.Handle, "You need to be patient.");
//Do your saving here.
}
finally
{
ShutdownBlockReasonDestroy(this.Handle);
}
}
鼓励使用简短的原因字符串,因为用户通常不会阅读长消息。吸引注意力的东西,例如 "Saving data" 或 "Flushing changes to disk"。请注意 "do it anyway I'm an impatient user" 按钮。