-3

我有一些线程正在运行,一旦检测到错误,我想使用消息框之类的交互来继续执行或停止它。而且我不想在我的屏幕上出现多个 msgbox,所以我添加了一个信号量,只让 1 个线程完成这项工作。但它不起作用。所以我有以下情况:

    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;
  ////////////////////////////////////////
    }

如何暂停所有线程,除了将显示消息框并基于对话框继续执行或停止它的线程?

4

2 回答 2

1

您的主要问题是这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();
}

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

于 2013-08-05T16:09:47.067 回答
1

实际上,您代码中的问题是您没有停止其他线程或要求它跳过显示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();
}

希望这能解决您的问题。

于 2013-08-03T10:21:17.003 回答