【问题标题】:Program Not Responding程序无响应
【发布时间】:2009-09-30 02:42:06
【问题描述】:

好的,嗨,我正在 Microsoft Visual Studio 中制作一个程序,每次运行它并单击开始(我有一个开始按钮),它都会执行我的编程操作,但表单总是冻结并且也没有显示我想要的内容(一旦我启动它就会显示“没有响应”)。这对完成这项工作很有好处,但我在表格上有一些应该显示的东西。虽然它一直冻结,但它并没有让我选择停止它,或者在它运行期间显示我设置更改的任何标签。对此的任何帮助将不胜感激。谢谢。

编辑:这就是我所拥有的:

        void CheckAll()
    {
        for (; ; )
        {
            CheckPixel();
            Application.DoEvents();
        }
    }

它一直在做 CheckPixel();,我认为这就是它冻结的原因。从来没有休息过。

【问题讨论】:

  • 为了得到最好的帮助,你需要放一些代码。否则一切都是在黑暗中拍摄。
  • 你到底想用你的 CheckAll() 方法做什么?我猜你正在尝试读取位图中的每个像素或其他东西。
  • 我什至不知道你可以做这样的无限循环。实际上,我不得不尝试这个构造,看看它是否会起作用,并且确实如此)。
  • 确实看起来比while (true)更有企业精神。

标签: c# winforms


【解决方案1】:

这通常意味着您正在阻塞 UI 线程(例如,在按钮单击处理程序中运行长时间操作)。您通常需要将长 I/O 操作卸载到 ThreadPool 或您自己的工作线程,而不是使用 UI 线程。这并不总是容易做到的,需要仔细设计和对并发性等有很好的理解。

【讨论】:

  • +1 - 良好的链接 - 在正确处理此类事情的正确方向上迈出了重要一步。
  • 也看看BackgroundWorker。 msdn.microsoft.com/en-us/library/…
  • 或许在处理多线程之前先了解一下 for 循环的工作原理?
【解决方案2】:

您的应用程序正在冻结,因为它处于无限循环中。我不知道你如何解决它,因为我不知道你到底想在这里做什么。

更新:因为我要睡觉了,所以我要在这里抛出一个总猜测。你的 CheckPixel() 方法应该有这样的签名:

public bool CheckPixel(int x, int y)
{
    Color color = _myBitmap.GetPixel(x, y);
    return (color == Color.Red);
}

其中_myBitmap 是表单范围的位图。那么你的 CheckAll() 方法应该是这样的:

public bool CheckAll()
{
    for (int x = 0; x < _myBitmap.Width; x++)
    {
        for (int y = 0; y < _myBitmap.Height; y++)
        {
            if (CheckPixel(x, y))
            {
                return true;
            }
        }
    }
    return false;
}

晚安,伙计们!我整个星期都在这里。

【讨论】:

  • 嘿,这些猴子是从哪里来的?为什么他们不坚持“单一出口点”的理念?
  • 好吧,好吧,也许这是个人喜好,我应该把它改成更详细的breaking 方案……好吧,那会令人困惑。好的。也许我应该不管它。但是,嘿,猴子看...
  • 不,你的方式更好,但我们必须与在他们的代码中添加“for (; ; )”的人一起采取婴儿步骤。 :)
  • 不,这可能有效,但我的 CheckPixel 与检查游戏中的像素有关,如果这些像素位于某个 (x, y),则执行命令。不过这只是给了我一个想法,对于布尔值,我会对其进行测试并告诉你结果。
  • @Brandon:听起来这你想要不断检查的东西,所以你可能想要使用 BackgroundWorker 来解决这个问题,正如 Ray 提到的那样(并输入 Thread.Sleep(0)Thread.Sleep(15) 在您的循环中,而不是 DoEvents())。
【解决方案3】:

将您的程序放在一个 try-catch 块中,然后在消息框中打印任何抛出的异常。 http://msdn.microsoft.com/en-us/library/0yd65esw%28VS.80%29.aspx

另外,请尝试在点击点插入断点,以确定它在哪里冻结。

【讨论】:

    【解决方案4】:

    为什么不用 Threading.Thread.Sleep(0) 而不是 Application.DoEvents()?我不是专家,但我更喜欢 Thread.Sleep 而不是 DoEvents。

    【讨论】:

    • 这是否允许 UI 响应?如果它在睡觉,它会如何反应?我得试试看。谢谢!
    • 它不允许 UI 响应 AFAIK。主 UI 线程上的 Sleep() 只会阻塞,直到计时器结束,不允许线程处理任何与 UI 相关的内容。
    • 好吧,我不确定,但我认为它可以让 CPU 执行可以释放其他进程的其他任务。我不认为它会阻塞。
    【解决方案5】:

    你需要有某种方式退出循环。

    你的 for 循环是否需要逻辑?到 ? (如

    for(int i = 0; , < 100; 1++) 
    

    会循环 100 次

    for(;;)
    {
       if(SomeCondition == true)
       {
          break;
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-16
      • 1970-01-01
      • 2022-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多