我的程序需要在关闭前做一些简单的操作,在网上搜到可以用SetConsoleCtrlHandler这个方法。部分代码:using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
namespace ConsoleColsed
{
public delegate bool ConsoleCtrlDelegate(int dwCtrlType);
public class ClsMain
{
public static StreamWriter sw; [DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
//当用户关闭Console时,系统会发送次消息
const int CtrlC = 0;
const int CTRL_CLOSE_EVENT = 2;
const int CTRL_LOGOFF_EVENT = 5;
const int CTRL_SHUTDOWN_EVENT = 6; public static void Main()
{
sw = new StreamWriter("close.txt");
sw.WriteLine("Test started at " + DateTime.Now.ToString("hh:mm:ss"));
ClsMain cls=new ClsMain();
Console.WriteLine("start");
//
// 其他代码。
//
Console.Read();
sw.Close();
} public ClsMain()
{
ConsoleCtrlDelegate newDelegate=new ConsoleCtrlDelegate(HandlerRoutine);
GC.KeepAlive(newDelegate);
SetConsoleCtrlHandler(newDelegate, true);
} public static bool HandlerRoutine(int CtrlType)
{
switch (CtrlType)
{
case CTRL_CLOSE_EVENT:
sw.WriteLine("user close");
break;
case CTRL_LOGOFF_EVENT:
sw.WriteLine("log off");
break;
case CTRL_SHUTDOWN_EVENT:
sw.WriteLine("shut down");
break;
}
sw.WriteLine("Test stopped at " + DateTime.Now.ToString("hh:mm:ss"));
sw.Close(); return false;
}
}
}测试时发现,如果运行较短时间(十几分钟内)后手动关闭,可以正常处理结束。但如果运行时间较长,比如超过一个小时,关闭就出现异常,会弹出Windows无法结束程序的对话框。请高手看看什么原因,多谢了。“其他代码”部分主要是不断的用IE打开不同的网页,然后关闭,其中用了大量的System.Threading.Thread.Sleep(),而且有很多写文件的操作。但整个程序完全是单线程的。如果把其他代码部分全部去掉,只留下 Console.Read();超过一个小时还是可以正常处理关闭事件。
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
namespace ConsoleColsed
{
public delegate bool ConsoleCtrlDelegate(int dwCtrlType);
public class ClsMain
{
public static StreamWriter sw; [DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
//当用户关闭Console时,系统会发送次消息
const int CtrlC = 0;
const int CTRL_CLOSE_EVENT = 2;
const int CTRL_LOGOFF_EVENT = 5;
const int CTRL_SHUTDOWN_EVENT = 6; public static void Main()
{
sw = new StreamWriter("close.txt");
sw.WriteLine("Test started at " + DateTime.Now.ToString("hh:mm:ss"));
ClsMain cls=new ClsMain();
Console.WriteLine("start");
//
// 其他代码。
//
Console.Read();
sw.Close();
} public ClsMain()
{
ConsoleCtrlDelegate newDelegate=new ConsoleCtrlDelegate(HandlerRoutine);
GC.KeepAlive(newDelegate);
SetConsoleCtrlHandler(newDelegate, true);
} public static bool HandlerRoutine(int CtrlType)
{
switch (CtrlType)
{
case CTRL_CLOSE_EVENT:
sw.WriteLine("user close");
break;
case CTRL_LOGOFF_EVENT:
sw.WriteLine("log off");
break;
case CTRL_SHUTDOWN_EVENT:
sw.WriteLine("shut down");
break;
}
sw.WriteLine("Test stopped at " + DateTime.Now.ToString("hh:mm:ss"));
sw.Close(); return false;
}
}
}测试时发现,如果运行较短时间(十几分钟内)后手动关闭,可以正常处理结束。但如果运行时间较长,比如超过一个小时,关闭就出现异常,会弹出Windows无法结束程序的对话框。请高手看看什么原因,多谢了。“其他代码”部分主要是不断的用IE打开不同的网页,然后关闭,其中用了大量的System.Threading.Thread.Sleep(),而且有很多写文件的操作。但整个程序完全是单线程的。如果把其他代码部分全部去掉,只留下 Console.Read();超过一个小时还是可以正常处理关闭事件。
几个小时的测试我就不做了,给你几个方案你试一下。
一、在其他代码执行部分加个判断,每次开始一个新的操作前先判断一个变量的值,运行继续执行的才执行,否则就停止执行,该值在HandlerRoutine中设置关闭。
二、去掉这行代码“ClsMain cls=new ClsMain();”后看看还会不会出现关不掉程序的情况。
1,这个方法基本没用。因为程序的大部分时间处于Sleep状态。“其他代码”大致是一个循环,运行几秒钟,然后会Sleep(100)秒。
2,这行不能去,因为“其他代码”还有很多初始化的工作。 这个函数也会有影响?
Unhandled Exception: System.AccessViolationException: Attempted to read or write
protected memory. This is often an indication that other memory is corrupt.
{
sw = new StreamWriter("close.txt");
sw.WriteLine("Test started at " + DateTime.Now.ToString("hh:mm:ss")); ConsoleCtrlDelegate newDelegate = new ConsoleCtrlDelegate(HandlerRoutine);
SetConsoleCtrlHandler(newDelegate, true);
Console.WriteLine("start"); //
// 其他代码。
Console.Read();
sw.Close();
GC.KeepAlive(newDelegate);
}