【问题标题】:Dialog box to abort a while-loop in C++/CLI在 C++/CLI 中中止 while 循环的对话框
【发布时间】:2011-10-31 18:12:37
【问题描述】:

我在函数中执行了一个 while 循环。在执行循环时,我希望在 Windows 的屏幕上显示一个带有“中止”按钮的对话框。如果我按下 Abort 按钮,程序将终止 while 循环。就像复制文件时弹出的对话框。有人可以建议一种简单的方法来使用 C++/CLI 或类似的东西来做到这一点吗?

由于我对 C++/CLI 没有太多经验,如果您能提供代码 sn-ps 或示例代码,我将不胜感激。

【问题讨论】:

  • 你需要使用一个线程才能工作。使用 BackgroundWorker。

标签: windows c++-cli


【解决方案1】:

使用单独的线程是执行此操作的现代方法,但还有另一种方法。

您可以提取 while 循环的内容并将它们放入事件处理程序中。安排让消息循环一次又一次地调用此事件处理程序,直到它完成工作(例如,使用计时器或空闲处理)。同时,您可以显示一个非模态弹出对话框。这就是打印在先发制人的多任务时代的工作方式。见SetAbortProc。

我推荐其他人列出的第二种线程方法。我只是想指出这不是唯一的方法。

【讨论】:

    【解决方案2】:

    while 循环的构造是简单的部分。困难的是您必须将中止对话框放在不同的线程中,然后将while 条件中的标志与对话框协调。这通常使用信号量来处理,这些信号量已知难以编码而没有微妙的副作用。

    while 循环至少需要一种机制,允许处理事件队列并定期检查中止信号量状态的变化。

    //psuedo-code below
    bool f_abort = false;
    while (!f_abort)
    {
        do_partial_work();
        f_abort = checkForAbort();
        sleep(0); // don't want to lock the CPU
    }
    

    我不是线程方面的专家,所以我必须向您指出其他资源,以便在 checkForAbort() 中做什么。

    Windows Forms Threading and Events - ListBox updates promptly but progressbar experiences huge delay

    Win32 synchronization

    Is putting thread on hold optimal?

    Thread for Windows form

    【讨论】:

      【解决方案3】:

      一个简单(但很差)的例子可能是这个:

      #include "stdafx.h"
      #include "windows.h"
      
      #using <System.Windows.Forms.dll>
      
      using namespace System;
      using namespace System::Windows::Forms;
      using namespace System::Threading;
      
      DialogResult *res=new DialogResult(DialogResult::No);
      
      void waitForUserAction()
      {
          while(*res==DialogResult::No)
          {
          *res=System::Windows::Forms::MessageBox::Show("Exit the loop ? YES/NO","TEST",
                      MessageBoxButtons::YesNo,MessageBoxIcon::Question);
          if(*res==DialogResult::Yes)
              Console::WriteLine(L"Exit by user");
          }
      }
      
      int main()
      {
      
          ThreadStart ^start=gcnew ThreadStart(waitForUserAction);
          Thread ^pThread=gcnew Thread(start);
          int a=0;
      
          pThread->Start();
          while(*res!=DialogResult::Yes)
          {
              a=a+1;
              Console::WriteLine(L"Loop processing here...{0}",a);
          }
          //pThread->Abort();
          return 0;
      }
      

      您可以查看此article 以获取有关该主题的更多信息...

      【讨论】:

      • 请不要使用Thread.Abort() 来管理应用程序的流程。这是危险的,应该只在真正需要时才使用,这里不是这种情况。
      • @ildjarn:您只能从创建它们的线程访问 GUI 对象,但完全可以有多个 UI 线程。
      • @Ben :我承认你可能比我更了解这一点,但我的强烈印象是 WinForms 特别需要单个 STA 线程。
      • @ildjarn:刚刚测试过它并按预期工作正常。 dl.dropbox.com/u/6919979/TwoUIThreads.7z
      • @Ben :你说得对,MessageBox 文档明确表示它的静态成员都是线程安全的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-21
      • 1970-01-01
      • 2012-11-11
      • 2022-01-21
      • 2022-11-03
      • 2020-04-10
      相关资源
      最近更新 更多