title: Thread safe re-initialization of concurrent dictionary
body: <p>I want to know if the following code is thread safe, which I assume it is not. And how I could possibly make it thread safe?</p>
  
  <p>Basically I have a <code>ConcurrentDictionary</code> which acts as a cache for a database table. I want to query the DB every 10 seconds and update the db cache. There will be other threads querying this dictionary the whole time.  </p>
  
  <p>I can't just use <code>TryAdd</code> as there may also me elements which have been removed. So I decided instead of searching through the entire dictionary to possibly update, add or remove. I would just reinitialize the dictionary. Please do tell me if this is a silly idea.</p>
  
  <p>My concern is that when I reinitialize the dictionary the querying threads will not longer by thread safe for the instance when the initialization takes place. For that reason I have used a lock for the dictionary when updating it, However I am not sure if this is correct as the object changes in the lock?</p>
  
  <pre><code>private static System.Timers.Timer updateTimer;
  private static volatile Boolean _isBusyUpdating = false;
  private static ConcurrentDictionary&lt;int, string&gt; _contactIdNames;
  
  public Constructor()
  {
      // Setup Timers for data updater         
      updateTimer = new System.Timers.Timer();
      updateTimer.Interval = new TimeSpan(0, 0, 10, 0).TotalMilliseconds;
      updateTimer.Elapsed += OnTimedEvent;
      // Start the timer
      updateTimer.Enabled = true;
  }
  
  private void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
  {
      if (!_isBusyUpdating)
      {
          _isBusyUpdating = true;
          // Get new data values and update the list
          try
          {
              var tmp = new ConcurrentDictionary&lt;int, string&gt;();
              using (var db = new DBEntities())
              {
                  foreach (var item in db.ContactIDs.Select(x =&gt; new { x.Qualifier, x.AlarmCode, x.Description }).AsEnumerable())
                  {
                      int key = (item.Qualifier * 1000) + item.AlarmCode;
                      tmp.TryAdd(key, item.Description);
                  }
              }
              if (_contactIdNames == null)
              {
                  _contactIdNames = tmp;
              }
              else
              {
                  lock (_contactIdNames)
                  {
                      _contactIdNames = tmp;
                  }
              }
          }
          catch (Exception e)
          {
              Debug.WriteLine("Error occurred in update ContactId db store", e);
          }
          _isBusyUpdating = false;
      }
  }
  
      /// Use the dictionary from another Thread
      public int GetIdFromClientString(string Name)
      {
          try
          {
              int pk;
              if (_contactIdNames.TryGetValue(Name, out pk))
              {
                  return pk;
              }
          }
          catch { }
          //If all else fails return -1
          return -1;
      }
  </code></pre>