暂停messagebox的线程

本文关键字:线程 messagebox 暂停 | 更新日期: 2023-09-27 18:26:16

我有一些线程在运行,一旦检测到错误,我想使用像messagebox这样的交互来继续执行或停止它。我不希望屏幕上有多个messagebox,所以我添加了一个信号量,只让一个线程完成这项工作。但它不起作用。所以我有以下情况:

    private void DO_WORK()
    {
    //some code missing
            lock (_threadLock)
            {
                ++activeWorkers;
            }
            ThreadPool.QueueUserWorkItem(o =>
                {
                    WorkRequests(result);
                    lock (_threadLock)
                    {
                        --activeWorkers;
                        Monitor.Pulse(_threadLock);
                    }
                });
            lock (_threadLock)
            {
                if (STOP)
                    break;
                while (activeWorkers > THREADS)
                    Monitor.Wait(_threadLock);
            }
     }

    private void WorkRequests(string mystr)
    {
        string source = null;
        string result = null;
        bool processed = false;
        bool messageBoxShown = false;
   ///////////////////////////////////
      while(true)//this is for rechecking the bad ones
      {
            source = GetSource(mystr);
            if (source == "ERROR_LIMITED")
            {
              lock (_threadLock)
              {
                if (!messageBoxShown)//<--- check messageBoxShown
                {
                    if (MessageBox.Show("Blocked IP detected!'nPlease change it!", "test program", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK)
                    {
                        messageBoxShown = true; //<--- set to true
                    }
                    else
                        DoStop();
                }
              }
            }
          else
              break;
       }
            result = mystr + " - " + source;
  ////////////////////////////////////////
    }

如何暂停除显示消息框和基于对话框的线程之外的所有线程以继续执行或停止执行

暂停messagebox的线程

您的主要问题是messageBoxShown是一个局部变量,因此每个线程都有自己的副本。一个线程将其设置为true,其他线程将看不到。

如果你想让所有线程都能看到它,你必须在类作用域声明它:

private volatile bool messageBoxShown = false;
private void WorkRequests(string mystr)
{
    // other stuff
    lock (_threadLock)
    {
        if (messageBoxShown)
        {
            return;
        }
    }
    // do dialog stuff, then
    messageBoxShown = true;
}

此外,在您的代码中,您有:

if (!messageBoxShown)//<--- check messageBoxShown
{
    if (MessageBox.Show("Blocked IP detected!'nPlease change it!", "test program",
        MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK)
    {
        messageBoxShown = true; //<--- set to true
    }
    else
        DoStop();
}

如果用户按下Cancel,则messageBoxShown永远不会设置为true。所以每个线程都会显示消息框,除非你有其他方法阻止他们这样做

实际上,代码中的问题是您没有停止其他线程或要求它跳过显示MessageBox。您的代码实际上限制了可以执行的线程数MessageBox块到1,因此它们开始逐个显示。

相反,尝试类似的东西

private volatile bool messageBoxShown = false;//Declare a Instance variable
var source = validate(mystr);   
if (source == "ERROR")
{
    lock (_threadLock)
    {
        semaf.WaitOne();
    }
    if(messageBoxShown)<--- check messageBoxShown
    {
        return;// or skip showing messagebox do whatever you want
    }
    if (MessageBox.Show("Blocked IP detected!'nPlease change it!", "test program", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK) 
    {  
        lock (_threadLock)
        {
            messageBoxShown = true; <--- set to true
            semaf.Release();
        }
    }
    else
        DoStop();
}

希望这能解决你的问题。