1

我目前正在尝试设计一种阻塞方法,直到字典中的值发生变化。这里我使用的是 WaitForOpenSpot 方法。这只是一个粗略的草图。我知道它目前不是线程安全的。我最终会在稍后添加锁定/解锁。现在我想知道是否有更好的方法来做到这一点?任何其他建议也将不胜感激。

Class AccountStatus
{
  static bool OpenSpot = false;

  static private Dictionary<String, int> Transfer = InitializeContainer();

  static Dictionary<String , int> InitializeContainer ()
  {
       Dictionary<String, int> Transfer = new Dictionary<String, int>()
       Transfer.add("stat",0);
  }

  static void  Changestatus(string str , int val) //str = stat 
  {
      Transfer[str] = val;
      if(val == 1)
      {
          OpenSpot = true
      }        
  } 

  static void WaitForOpenSpot()
  {
      while(!OpenSpot)
      {
          Thread.sleep(2);
      }
  } 
}//end class
4

2 回答 2

3

看一下AutoResetEvent类。

从您的代码中采用给您一个粗略的例子(可能无法编译):

private static AutoResetEvent resetEvent = new AutoResetEvent(false); 

static void WaitForOpenSpot()
{  
    resetEvent.WaitOne();
}

static void ChangeStatus(string str, int val)
{
   Transfer[str] = val;
   if (val == 1)
   {
       resetEvent.Set();
   }
}
于 2013-02-12T18:23:54.313 回答
0

像这样的正常模式是使用Monitor.Wait/ Monitor.PulseAll。要使用这些方法,应该定义一个只能在锁内更改的等待条件,并让任何可能更改该条件的代码PulseAll在完成后对锁执行操作。

例如:字典 myDict;

//Code that waits for magic key value:
lock(myDict)
{
    int myNumber;
    while (!myDict.TryGetValue(myKey, out myNumber) || myNumber < valueOfInterest)
        Monitor.Wait(myDict);
}

//Code that changes anything in myDict:
lock(myDict)
{
    myDict[theKey] = theValue;
    Monitor.PulseAll(myDict);
}

任何时候 Dictionary 中有任何变化,所有等待某个键以保持某个值的等待线程将一个接一个地检查它是否发生变化,然后继续或返回等待。

请注意,如果Monitor.Wait有时在没有脉冲的情况下提前自发返回,则不会影响此代码的正确性。虽然Monitor.Wait通常不会自发唤醒,但正确编写的代码通常可以容忍这种唤醒,并且会被这种唤醒破坏的代码通常也会以其他方式被破坏。

于 2013-02-12T19:13:35.267 回答