我有一个控制台应用程序,它使用BackgroundWorker
来运行无限循环。
我正试图捕捉近距离事件并做一些事情。
我使用了一些google搜索解决方案,并提出了以下建议:
class Program
{
private static bool keepAlive = false;
private static BackgroundWorker bgWorker = new BackgroundWorker();
private static void runThread ()
{
while (keepAlive) {}
}
private bool ConsoleClosingCheck(CtrlTypes ctrlType)
{
switch (ctrlType)
{
case CtrlTypes.CTRL_CLOSE_EVENT:
keepAlive = false;
break;
}
return true;
}
[DllImport("Kernel32")]
public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);
public delegate bool HandlerRoutine(CtrlTypes CtrlType);
public enum CtrlTypes
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}
public static void Start ()
{
keepAlive = true;
bgWorker.DoWork += (sender, e) => runThread();
bgWorker.RunWorkerAsync();
}
public static void Main(string[] args)
{
Program p = new Program();
SetConsoleCtrlHandler(new HandlerRoutine(p.ConsoleClosingCheck), true);
p.Start();
}
}
当我调试它并使用“X”(正常关闭)关闭控制台时,它不会停在case
,而是应用程序崩溃。
有什么想法吗?
答案 0 :(得分:0)
示例代码不能为我编译:
Member 'Program.Start()' cannot be accessed with an instance reference;
我怀疑问题只是因为您创建的'p'对象没有托管根(没有托管类保留对它的引用),只有一个非托管回调引用它。
这意味着p可以收集垃圾,在调用回调时导致失败。
我尝试将示例Program类转换为静态。它没有在Start()方法中等待,所以我在start方法结束时添加了对BackgroundWorker.IsBusy的等待。 我还在回调中添加了这样的等待;否则,它只是一场比赛,看看doWork方法的其余部分是否可以执行:
case CtrlTypes.CTRL_CLOSE_EVENT:
{
keepAlive = false;
while (bgWorker.IsBusy)
{
Thread.Sleep(100);
}
break;
}