暂停消息框的线程

时间:2013-08-03 04:52:26

标签: c# threadpool mutex semaphore

我有一些线程正在运行,一旦检测到错误,我想使用像messagebox这样的交互来继续执行或停止它。而且我不想在屏幕上显示多个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;
  ////////////////////////////////////////
    }

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

2 个答案:

答案 0 :(得分: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();
}

希望这能解决您的问题。

答案 1 :(得分: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。所以每个线程都会显示消息框,除非你有其他方法可以阻止他们这样做。