【发布时间】:2012-03-08 14:01:32
【问题描述】:
以下程序在“Console.ReadKey()”上引发错误。
如何在禁用控制台后重新启用它?
using System;
using System.Threading;
using System.Runtime.InteropServices;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem((o) =>
{
Thread.Sleep(1000);
IntPtr stdin = GetStdHandle(StdHandle.Stdin);
CloseHandle(stdin);
});
Console.ReadLine();
Console.Write("ReadLine() successfully aborted by background thread.\n");
Console.Write("[any key to exit]");
Console.ReadKey(); // Throws an exception "Cannot read keys when either application does not have a console or when console input has been redirected from a file. Try Console.Read."
}
// P/Invoke:
private enum StdHandle { Stdin = -10, Stdout = -11, Stderr = -12 };
[DllImport("kernel32.dll")]
private static extern IntPtr GetStdHandle(StdHandle std);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hdl);
}
}
专家补充
如果您想知道,我需要能够在 C# 中终止运行 ReadLine() 的后台线程。这似乎是唯一的方法(thread.Abort 不起作用,因为 ReadLine() 在操作系统的内部深处以非托管代码运行)。 StackOverflow 上有很多关于这个话题的讨论,没有人真正发现(或发布)中止 Console.ReadLine() 的令人满意的方法。我认为这段代码在正确的轨道上——如果我们能在禁用控制台后重新启用它。
【问题讨论】:
-
如果您关闭手柄...您将不得不再次手动打开它。考虑到您刚刚关闭了 Handle,因此无法保证您可以再次使用相同的 Handle。您确定关闭正确的手柄吗?我必须相信有一种更简单的方法可以中止 Readline,然后关闭标准输入的血腥句柄。
-
@Ramhound 我希望有一种更简单的方法来中止 ReadLine。我已经尝试了一切 - .Abort,向应用程序发送密钥(仅适用于当前焦点)等。如果有更好的方法,我会全力以赴。
-
@Ramhound 我能想到的唯一其他方法是在 100% 托管的 C# 中编写 ReadLine 的克隆,因此 .Abort 将起作用,与几行 Win32 代码相比,这肯定更复杂.
标签: c# .net visual-studio