Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 控制台:检查按键(Esc)_C# - Fatal编程技术网

C# 控制台:检查按键(Esc)

C# 控制台:检查按键(Esc),c#,C#,在您标记这一点之前,我已经尝试了这里找到的几种解决方案(我发誓它不是重复的),并最终导致VS崩溃的错误 编辑:有人说我的循环不起作用。问题不在这里,它与按键有关 这是我的原始代码: while (true) { Console.WriteLine("Voer een getal in : "); string invoer = Console.ReadLine();

在您标记这一点之前,我已经尝试了这里找到的几种解决方案(我发誓它不是重复的),并最终导致VS崩溃的错误

编辑:有人说我的循环不起作用。问题不在这里,它与按键有关

这是我的原始代码:

        while (true)
            {
                Console.WriteLine("Voer een getal in : ");
                string invoer = Console.ReadLine();
                Console.Write("Voer de macht in waarmee u wilt vermenigvuldigen :");
                string macht = Console.ReadLine();

                int getal = Convert.ToInt32(invoer);
                int getalmacht = Convert.ToInt32(macht);

                int uitkomst = (int)Math.Pow(getal, getalmacht);
                Console.WriteLine("De macht van " + getal + " is " + uitkomst + " .");
                Console.ReadLine();


            }
它工作得很好,但它没有寻找按键

下面是一个检查按键并不会抛出错误的:

namespace Democonsole
{
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Press ESC to stop.");

        do
        {
            while (!Console.KeyAvailable)
            {

                Console.WriteLine("Voer een getal in : ");
                string invoer = Console.ReadLine();
                Console.Write("Voer de macht in waarmee u wilt vermenigvuldigen :");
                string macht = Console.ReadLine();

                int getal = Convert.ToInt32(invoer);
                int getalmacht = Convert.ToInt32(macht);

                int uitkomst = (int)Math.Pow(getal, getalmacht);
                Console.WriteLine("De macht van " + getal + " is " + uitkomst + " .");
                Console.ReadLine();


            }
        } while (Console.ReadKey(true).Key != ConsoleKey.Escape);




    }
}
}

但是,它在运行crash时会执行此操作,并给出打印屏幕中显示的错误

还有别的办法吗

编辑:添加了更多因请求而尝试的解决方案示例

    static void Main(string[] args)
{
    var myWorker = new MyWorker();
    myWorker.DoStuff();
    Console.WriteLine("Press any key to stop...");
    Console.ReadKey();
}
中断


错误消息告诉您关于该错误所需了解的几乎所有信息,即您正在尝试将字符串转换为整数,而该字符串无法转换为整数。可能是因为它是空的

不过,这只是问题的一部分,我将在稍后讨论

首先,您的循环结构是错误的。只要没有等待读取的按键,内部循环就会运行。但是就在循环体的末尾,您明确地清除了控制台缓冲区的内容,因此它永远不会退出内部循环

考虑这个最小的例子:

while (!Console.KeyAvailable)
{
    Console.ReadLine();
}
假设在遇到
while
语句(将跳过整个过程)时没有等待读取的键,内部语句将累积击键中的字符,直到按enter键,然后将字符作为字符串返回。几微秒后,它会检查您是否在回车后按下了另一个键,这几乎是不可能的。因此,这是一种编写无限循环的奇怪方式

下一个问题是,您请求用户输入,并假设输入是有效的。不是的,这就是你之前得到的异常的原因。始终假定用户将输入您的程序不期望的内容,并找出如何处理出错的问题

例如:

string invoer = Console.ReadLine();
int getal;
if (!int.TryParse(invoer, out getal))
{
    Console.WriteLine("Invalid value '{0}'", invoer);
    continue;
}
如果该值未转换为数字,则将对此进行投诉,并返回到循环的开头。如果值为空,您可能还希望尝试退出循环:

string invoer = Console.ReadLine();
if (string.IsNullOrEmpty(invoer))
    break;
int getal;
if (!int.TryParse(invoer, out getal))
{
    Console.WriteLine("Invalid value '{0}'", invoer);
    continue;
}

这至少为您提供了一条跳出循环的途径,而您目前还没有这种途径。

我有一个完全替代的解决方案,使用以下解决方案。标题是,您希望选中esc。就是这样。高度复制自:

ConsoleHoKeyManager.cs>

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;

namespace ConsoleHotKey
{
    public static class HotKeyManager
    {
        public static event EventHandler<HotKeyEventArgs> HotKeyPressed;

        public static int RegisterHotKey(Keys key, KeyModifiers modifiers)
        {
            _windowReadyEvent.WaitOne();
            int id = System.Threading.Interlocked.Increment(ref _id);
            _wnd.Invoke(new RegisterHotKeyDelegate(RegisterHotKeyInternal), _hwnd, id, (uint)modifiers, (uint)key);
            return id;
        }

        public static void UnregisterHotKey(int id)
        {
            _wnd.Invoke(new UnRegisterHotKeyDelegate(UnRegisterHotKeyInternal), _hwnd, id);
        }

        delegate void RegisterHotKeyDelegate(IntPtr hwnd, int id, uint modifiers, uint key);
        delegate void UnRegisterHotKeyDelegate(IntPtr hwnd, int id);

        private static void RegisterHotKeyInternal(IntPtr hwnd, int id, uint modifiers, uint key)
        {
            RegisterHotKey(hwnd, id, modifiers, key);
        }

        private static void UnRegisterHotKeyInternal(IntPtr hwnd, int id)
        {
            UnregisterHotKey(_hwnd, id);
        }

        private static void OnHotKeyPressed(HotKeyEventArgs e)
        {
            if (HotKeyManager.HotKeyPressed != null)
            {
                HotKeyManager.HotKeyPressed(null, e);
            }
        }

        private static volatile MessageWindow _wnd;
        private static volatile IntPtr _hwnd;
        private static ManualResetEvent _windowReadyEvent = new ManualResetEvent(false);
        static HotKeyManager()
        {
            Thread messageLoop = new Thread(delegate()
            {
                Application.Run(new MessageWindow());
            });
            messageLoop.Name = "MessageLoopThread";
            messageLoop.IsBackground = true;
            messageLoop.Start();
        }

        private class MessageWindow : Form
        {
            public MessageWindow()
            {
                _wnd = this;
                _hwnd = this.Handle;
                _windowReadyEvent.Set();
            }

            protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_HOTKEY)
                {
                    HotKeyEventArgs e = new HotKeyEventArgs(m.LParam);
                    HotKeyManager.OnHotKeyPressed(e);
                }

                base.WndProc(ref m);
            }

            protected override void SetVisibleCore(bool value)
            {
                // Ensure the window never becomes visible
                base.SetVisibleCore(false);
            }

            private const int WM_HOTKEY = 0x312;
        }

        [DllImport("user32", SetLastError = true)]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

        [DllImport("user32", SetLastError = true)]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        private static int _id = 0;
    }


    public class HotKeyEventArgs : EventArgs
    {
        public readonly Keys Key;
        public readonly KeyModifiers Modifiers;

        public HotKeyEventArgs(Keys key, KeyModifiers modifiers)
        {
            this.Key = key;
            this.Modifiers = modifiers;
        }

        public HotKeyEventArgs(IntPtr hotKeyParam)
        {
            uint param = (uint)hotKeyParam.ToInt64();
            Key = (Keys)((param & 0xffff0000) >> 16);
            Modifiers = (KeyModifiers)(param & 0x0000ffff);
        }
    }

    [Flags]
    public enum KeyModifiers
    {
        Alt = 1,
        Control = 2,
        Shift = 4,
        Windows = 8,
        NoRepeat = 0x4000,
        None = 0
    }
}
使用系统;
使用System.Windows.Forms;
使用System.Runtime.InteropServices;
使用系统线程;
命名空间控制台快捷键
{
公共静态类热键管理器
{
按下公共静态事件事件处理程序热键;
公共静态int寄存器hotKey(键键、键修饰符修饰符)
{
_windowReadyEvent.WaitOne();
int id=系统线程联锁增量(参考id);
_调用(新的RegisterHotKeyDelegate(RegisterHotKeyInternal),hwnd,id,(uint)修饰符,(uint)键);
返回id;
}
公共静态void unregister热键(int-id)
{
_调用(新的UnRegisterHotKeyDelegate(UnRegisterHotKeyInternal),\u hwnd,id);
}
委托无效寄存器hotKeyDelegate(IntPtr hwnd、int id、uint修饰符、uint键);
委托无效取消注册HotkeyDelegate(IntPtr hwnd,int id);
私有静态无效寄存器hotKeyInternal(IntPtr hwnd、int id、uint修饰符、uint key)
{
注册表快捷键(hwnd、id、修饰符、键);
}
私有静态void UnRegisterHotKeyInternal(IntPtr hwnd,int id)
{
取消注册热键(_hwnd,id);
}
热键按下时私有静态无效(热键事件参数e)
{
if(HotKeyManager.HotKeyPressed!=null)
{
热键管理器。热键按下(null,e);
}
}
私有静态易失性消息窗口;
私有静态易失性IntPtr\u hwnd;
专用静态手动复位事件\u windowReadyEvent=新手动复位事件(假);
静态热键管理器()
{
Thread messageLoop=新线程(委托()
{
运行(newmessagewindow());
});
messageLoop.Name=“MessageLoopThread”;
messageLoop.IsBackground=true;
messageLoop.Start();
}
私有类消息窗口:窗体
{
公共消息窗口()
{
_wnd=这个;
_hwnd=this.Handle;
_windowReadyEvent.Set();
}
受保护的覆盖无效WndProc(参考消息m)
{
if(m.Msg==WM_热键)
{
HotKeyEventArgs e=新的HotKeyEventArgs(m.LParam);
热键管理器。按下热键(e);
}
基准WndProc(参考m);
}
受保护的覆盖无效SetVisibleCore(布尔值)
{
//确保窗口永远不可见
base.SetVisibleCore(false);
}
私有常量int WM_热键=0x312;
}
[DllImport(“user32”,SetLastError=true)]
私有静态外部布尔寄存器hotkey(IntPtr hWnd、int id、uint fsModifiers、uint vk);
[DllImport(“user32”,SetLastError=true)]
私有静态外部bool unregister热键(IntPtr hWnd,intid);
私有静态int_id=0;
}
公共类HotKeyEventArgs:EventArgs
{
公共只读密钥;
公共只读键修饰符修饰符;
public HotKeyEventArgs(键、键修改器和修改器)
{
这个。键=键;
this.Modifiers=修饰符;
}
public HotKeyEventArgs(IntPtr hotKeyParam)
{
uint参数=(uint)hotKeyParam.T
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;

namespace ConsoleHotKey
{
    public static class HotKeyManager
    {
        public static event EventHandler<HotKeyEventArgs> HotKeyPressed;

        public static int RegisterHotKey(Keys key, KeyModifiers modifiers)
        {
            _windowReadyEvent.WaitOne();
            int id = System.Threading.Interlocked.Increment(ref _id);
            _wnd.Invoke(new RegisterHotKeyDelegate(RegisterHotKeyInternal), _hwnd, id, (uint)modifiers, (uint)key);
            return id;
        }

        public static void UnregisterHotKey(int id)
        {
            _wnd.Invoke(new UnRegisterHotKeyDelegate(UnRegisterHotKeyInternal), _hwnd, id);
        }

        delegate void RegisterHotKeyDelegate(IntPtr hwnd, int id, uint modifiers, uint key);
        delegate void UnRegisterHotKeyDelegate(IntPtr hwnd, int id);

        private static void RegisterHotKeyInternal(IntPtr hwnd, int id, uint modifiers, uint key)
        {
            RegisterHotKey(hwnd, id, modifiers, key);
        }

        private static void UnRegisterHotKeyInternal(IntPtr hwnd, int id)
        {
            UnregisterHotKey(_hwnd, id);
        }

        private static void OnHotKeyPressed(HotKeyEventArgs e)
        {
            if (HotKeyManager.HotKeyPressed != null)
            {
                HotKeyManager.HotKeyPressed(null, e);
            }
        }

        private static volatile MessageWindow _wnd;
        private static volatile IntPtr _hwnd;
        private static ManualResetEvent _windowReadyEvent = new ManualResetEvent(false);
        static HotKeyManager()
        {
            Thread messageLoop = new Thread(delegate()
            {
                Application.Run(new MessageWindow());
            });
            messageLoop.Name = "MessageLoopThread";
            messageLoop.IsBackground = true;
            messageLoop.Start();
        }

        private class MessageWindow : Form
        {
            public MessageWindow()
            {
                _wnd = this;
                _hwnd = this.Handle;
                _windowReadyEvent.Set();
            }

            protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_HOTKEY)
                {
                    HotKeyEventArgs e = new HotKeyEventArgs(m.LParam);
                    HotKeyManager.OnHotKeyPressed(e);
                }

                base.WndProc(ref m);
            }

            protected override void SetVisibleCore(bool value)
            {
                // Ensure the window never becomes visible
                base.SetVisibleCore(false);
            }

            private const int WM_HOTKEY = 0x312;
        }

        [DllImport("user32", SetLastError = true)]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

        [DllImport("user32", SetLastError = true)]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        private static int _id = 0;
    }


    public class HotKeyEventArgs : EventArgs
    {
        public readonly Keys Key;
        public readonly KeyModifiers Modifiers;

        public HotKeyEventArgs(Keys key, KeyModifiers modifiers)
        {
            this.Key = key;
            this.Modifiers = modifiers;
        }

        public HotKeyEventArgs(IntPtr hotKeyParam)
        {
            uint param = (uint)hotKeyParam.ToInt64();
            Key = (Keys)((param & 0xffff0000) >> 16);
            Modifiers = (KeyModifiers)(param & 0x0000ffff);
        }
    }

    [Flags]
    public enum KeyModifiers
    {
        Alt = 1,
        Control = 2,
        Shift = 4,
        Windows = 8,
        NoRepeat = 0x4000,
        None = 0
    }
}
using ConsoleHotKey;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Democonsole
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Press ESC to stop.");
            HotKeyManager.RegisterHotKey(Keys.Escape, KeyModifiers.None);
            HotKeyManager.HotKeyPressed += new EventHandler<HotKeyEventArgs>(Console_CancelKeyPress);
            while (true)
            {
                Console.WriteLine("Voer een getal in : ");
                string invoer = Console.ReadLine();
                Console.Write("Voer de macht in waarmee u wilt vermenigvuldigen :");
                string macht = Console.ReadLine();

                int getal = Convert.ToInt32(invoer);
                int getalmacht = Convert.ToInt32(macht);

                int uitkomst = (int)Math.Pow(getal, getalmacht);
                Console.WriteLine("De macht van " + getal + " is " + uitkomst + " .");
                Console.ReadLine();
            }
        }

        static void Console_CancelKeyPress(object sender, HotKeyEventArgs e)
        {
            Environment.Exit(0);
        }
    }
}