如何从.NET应用程序调用控制台应用程序并捕获控制台中生成的所有输出?
(请记住,我不想先将信息保存在文件中,然后重新保存,因为我希望将其作为实时信息接收.)
我正在制作一个在控制台模式下工作的交互式基准测试程序,并希望能够通过按Ctrl + C或Ctrl + Break一次中断当前计算,而后续按下应该像往常一样,终止程序.但是,如果当前没有执行任何计算,则第一次按Ctrl + C将导致终止.
起初,这看起来像一个简单的任务.我创建了一个带有明显EnableHandler()
和DisableHandler()
例程的静态类,以及一个依赖于先前状态的行为的处理函数:如果已经请求中断,那么只需停下来返回,否则设置arg.Cancel
并引发中断请求标志.因此,当基准测试开始时,它启用处理程序,然后检查每个主要周期的中断标志; 完成后,如果需要,它会禁用处理程序并将中断请求传播到最顶层的调用者.
但是,这种方法只能运行一次:第一次删除处理程序后(无论是否曾经被触发),之后再次安装它不再有效 - 操作不会产生错误,但处理程序永远不会收到事件发生时控制.这是.NET事件处理中的预期行为吗?
关于Console.CancelKeyPress
SO和其他论坛有很多主题,但几乎没有人考虑删除处理程序,因此难怪他们没有遇到麻烦.尽管如此,在" 如何多次使用ConsoleCancelEventHandler "中提到了一些类似的(?)问题,但该应用程序是一个复杂的GUI前端,用于按需启动的几个外部控制台实用程序,该问题显然与尝试时出现的显式异常有关.第二次添加处理程序, - 这不是我的情况.
在被告知安慰各种.NET版本操作相关先前存在的bug,如果这样的行为是不正常的,通过.NET故障引起的或特定于Visual Basic,我不会感到惊讶,(我不知道是否AddHandler
和RemoveHandler
在VB.NET完全等同于C#中的+=
和-=
事件运算符.我目前在Windows 7 x86-64上使用.NET 4.5和Visual Basic 2012,并安装了所有可用的更新.
作为一种解决方法,我实际上不会在DisableHandler()
例程中删除处理程序,而只是切换一个标志:当清除此标志时,处理程序立即返回,就好像没有安装一样.但是,这种方法对我来说看起来很难看,我希望以适当的方式解决问题并实现目标.
PS.Chris Dunaway要求的当前代码:
' Usage example
Dim fAbort As Boolean = False
BreakHandler.Enable()
For Each oImplementation As Implementation In oCompetition.Implementations
Benchmark(oImplementation)
If BreakHandler.AbortRequested() Then fAbort = True : Exit For
Next
BreakHandler.Disable()
Return …
Run Code Online (Sandbox Code Playgroud)