2013-08-03 67 views
-2

我有一些线程正在运行,一旦检测到错误我想使用像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; 
    //////////////////////////////////////// 
    } 

我怎样可以暂停所有的线程除了一个,它会显示在MessageBox和基于对话框继续执行或停止呢?

+0

没有人??我问什么太复杂了? – ShaMora

+0

你会得到一个一个的messageboxes对吗? –

+0

是的,我想只有一个线程数量不多 – ShaMora

回答

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。所以每个线程都会显示消息框,除非您有其他方法来阻止他们这样做。

+0

感谢您的回复。我之前尝试在函数外面设置bool,它工作正常,但是它下次没有显示消息框,因为bool设置为true,因此检测到阻止ip。或者我错了? – ShaMora

+0

@ShaMora:在某些时候(大概当所有的线程完成当前的工作,也许?),你把它设置回“false”。 –

+0

函数validate(mystr)每5000次调用返回阻塞的IP一次,所以如果我使用这样的代码,它将工作在第一个5000,而下一个将不工作,即使我手动更改IP。我可以在当前线程完成当前任务后自动将其设置为false吗?我的意思是为未来而来 – ShaMora

1

其实在你的代码的问题是你不阻止其他线程或要求它跳过显示MessageBox你的代码实际上限制了线程的数量可以执行 的MessageBox块,于是他们开始展示ONY一个。

而是尝试这样

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(); 
} 

希望这将解决你的问题的东西。

+0

我现在只有一个消息框,但是当我按ok时,其他线程不会继续,实际上整个应用程序挂起,因为它被搁置。 – ShaMora

+0

你想要另一个线程做什么? –

+0

继续做同样的事情,直到阻止IP检测,然后单个消息框出现,我改变IP然后按OK,一切继续,直到下一次我得到一个块IP等 – ShaMora