【问题标题】:console application key release控制台应用程序密钥释放
【发布时间】:2014-07-25 18:03:02
【问题描述】:

我希望程序在按下特定键时播放哔声。 有什么方法可以在释放键时检测到它吗?然后中止播放该哔声的线程?

考虑以下示例:

   class Program
        {
        public static void Play()
        {
            while (true)
            {
                Console.Beep(400, 10000);//play for a long length, will be interrupted as soon as the key is released
            }
        }
        public static void Main(string[] args)
        {
             while(true)
             {
             ConsoleKeyInfo cki=Console.ReadKey(true);
             if(cki.Key==ConsoleKey.G)
                  {
                    Thread p = new Thread(Play);
                    p.Start();
                  }

             }
        }

我考虑过使用Thread.Abort(),但是它应该只在释放键 G 时中止上述线程 p。 实现一种在按住 G 键的同时短时间播放哔声的方法是行不通的,因为每次哔声之间可以听到很小的间隔。

因此,使用以下代码将播放短促的哔哔声,它们之间的间隔很小:

public static void Main()
    {

        ConsoleKeyInfo keyinfo;
        do
        {
            keyinfo = Console.ReadKey();

            Console.Beep(400, 10);
        }
        while (keyinfo.Key == ConsoleKey.G);
    }

相反,我希望发出一声长哔声,一松开键就停止。

【问题讨论】:

  • 检查这个答案,以及挂钩链接stackoverflow.com/a/8898251/752527
  • 尝试使用 KeyUp 事件处理程序
  • 这将需要我使用 Windows 窗体应用程序...没有它我有什么办法吗?
  • 这样做将使用多个console.beep 命令,这些命令将被听到许多音符,它们之间的间隔非常短。相反,我希望听到一声长长的 Console.beep,它会听到一声长长的连续哔声,只有在松开按键时才会停止

标签: c# multithreading console-application beep


【解决方案1】:

这是因为当你按住一个键时,键盘每秒最多会产生大约 31 次“击键”。这使您在击键和下一次击键之间有大约 32.25 毫秒的延迟。

现在因为 Console.ReadKey 正在阻塞线程,您将等待这 32.25 毫秒,然后再调用下一个 Beep,这会为每 10 毫秒哔声产生 22 毫秒的静默。

回到代码上来,您应该增加哔声时间以大致匹配击键之间的延迟。我省去了基于SystemInformation.KeyboardSpeed 的精确计算。如果你需要,我会添加它。

ConsoleKeyInfo keyinfo;

do
{
    keyinfo = Console.ReadKey();

    Console.Beep(400, 33);
}
while (keyinfo.Key == ConsoleKey.G);

【讨论】:

  • 第一次和第二次按键之间的时间取决于控制面板中设置的键盘延迟和重复率。
  • 恐怕它不起作用......因为 Console.Beep() 被阻塞......所以如果你的系统会检测到密钥然后播放 33 毫秒的哔声然后停止在对新密钥进行采样之前一段时间...您可以启动一个线程以异步哔哔声 33 毫秒(或更多),但我必须检查结果...不知道如果两个 Console.Beep( ) 调用重叠...
  • @MobyDisk 我刚刚简化了那部分并在第三段中提到了它,这不是解决方案的核心部分:)
  • @MorixDev 线程将在Beep 上被阻塞33 毫秒,然后返回ReadKey,发现按键现在可用。只需将键盘的速率设置为最高,看看是否可行。然后我将添加基于SystemInformation.KeyboardSpeed 的计算,使其适用于任何速度。
  • @Alireza:也许你不会听到它......但使用这种方法肯定会有一些沉默......
【解决方案2】:

它比其他建议的解决方案复杂得多,但我担心唯一的选择是从声音缓冲区播放哔哔声,其内容在按下键时被填满......我说的是使用 DirectSound API 和诸如此类的事情...也许http://msdn.microsoft.com/en-us/library/windows/desktop/bb318673(v=vs.85).aspx 可以成为调查这种可能性的一个很好的起点...

【讨论】:

    【解决方案3】:

    您编写的代码可以正常工作。

    使用包括:

    使用 System.Threading;

    我在 Visual Studio 2010 Ultimate 中以任何 CPU 构建模式运行了代码。

    它工作正常。

    从项目输出目录运行 .exe 文件。

    【讨论】:

    • 不,这样不行。这就是 OP 所说的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    相关资源
    最近更新 更多