Я хочу знать, является ли следующий код потокобезопасным, хотя я предполагаю, что это не так. И как я могу сделать это потокобезопасным?
В основном у меня есть ConcurrentDictionary
, который действует как кеш для таблицы базы данных. Я хочу запрашивать БД каждые 10 секунд и обновлять кеш БД. Другие потоки будут все время запрашивать этот словарь.
Я не могу просто использовать TryAdd
, так как могут быть также удаленные элементы. Поэтому я решил вместо того, чтобы искать по всему словарю, возможно, обновить, добавить или удалить. Я бы просто переинициализировал словарь. Пожалуйста, скажите мне, глупая ли это идея.
Меня беспокоит то, что когда я повторно инициализирую словарь, потоки запросов больше не будут потокобезопасными для экземпляра, когда происходит инициализация. По этой причине я использовал блокировку словаря при его обновлении. Однако я не уверен, правильно ли это, поскольку объект изменяется в блокировке?
private static System.Timers.Timer updateTimer;
private static volatile Boolean _isBusyUpdating = false;
private static ConcurrentDictionary<int, string> _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<int, string>();
using (var db = new DBEntities())
{
foreach (var item in db.ContactIDs.Select(x => 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;
}
Clear()
? - person Ric   schedule 12.10.2015static
и нестатический код? - person Enigmativity   schedule 12.10.2015_clientIdDbStore
и как она соотносится с_contactIdNames
? - person Enigmativity   schedule 12.10.2015