我的控制台应用程序正在执行一个完全专注于用户界面的线程,它在Console.ReadLine()
上花了很多时间阻塞(此调用花费的时间深入Windows的内部,超出了控制范围.NET框架)。
我需要中止这个帖子。但是,以下代码似乎不起作用:
this.UserInterfaceThread.Abort();
有什么想法吗? Thread.Interrupt()会有用吗?
更新
正如汉斯帕斯特所指出的那样:
CLR在中止线程时对线程的状态施加了相当明智的规则。 Thread.Abort()的危险是众所周知的,当然不能可靠地工作就是中止正在执行非托管代码的线程。调用Console.ReadLine()时就是这种情况,该线程深埋在Windows操作系统代码中。
解决方案是简单地将[enter]键击到当前运行的控制台应用程序中,该应用程序取消阻止Console.ReadLine(),以便线程立即中止。
我们不能使用SendKeys,因为这是特定于Windows窗体,它还需要当前窗口具有焦点。
解决方案是使用包含Windows SendInput()调用的inputsimulator.codeplex.com库。
参见示例代码:
.NET call to send [enter] keystroke into the current process, which is a console app?
答案 0 :(得分:6)
CLR在中止线程时对线程的状态施加了相当明智的规则。 Thread.Abort()的危险是众所周知的,当然不能可靠地工作就是中止正在执行非托管代码的线程。调用Console.ReadLine()时就是这种情况,该线程深埋在Windows操作系统代码中。
你将不得不以不同的方式做到这一点。一个显而易见的方法是让这个“用户界面”线程停止程序而不是相反。可以像“退出”命令或众所周知的“按任意键继续”消息一样简单。
或者将线程的IsBackground属性设置为true。现在您不必中止它,Windows将在Main()方法退出后关闭进程时终止它。
答案 1 :(得分:2)
我刚刚对其进行了测试,Thread.Abort()
和Thread.Interrupt()
都没有在调用Console.ReadLine()
的线程上工作,即使是通过StreamReader( new BufferedStream(...))
调用它。
我甚至尝试过调用Console.In.Close()
和Dispose()
。一旦你读完了,你就真的在那里;奇怪,因为这似乎打破了溪流的设计。
看起来您的唯一选择是使用@ Darin-Dimitrov提到的答案
编辑:
从列表中敲出另一个:尝试调用win32 api FreeConsole
。从Console.ReadLine()调用导致内存损坏异常。