Самый простой способ в этом случае убедиться, что вы получите то, что ожидаете, - это использовать lock
.
class Example()
{
Dictionary<string, string> dic1;
Dictionary<string, string> dic2;
private Object syncRoot;
public void Example()
{
dic1 = new Dictionary<string,string>(10);
dic2 = new Dictionary<string,string>(10);
syncRoot = new Object();
}
public string Method1(string param1)
{
lock(syncRoot) {
if(dic1.ContainsKey(param1))
{
return dic1[param1];
}
if(IsValidParam(param1))
{
dic1.Add(param1, param1);
return param1;
}
try
{
var params = GetValidParams(param1);
if(params.Count > 0)
{
foreach(var param in params)
{
if(!isValirParam(param)
continue;
dic1.Add(param1, param);
if(!dic2.ContainsKey(param1))
{
dic2.Add(param, param1);
}
return param;
}
}
else
{
dic2.Add(param1, param1);
return param1;
}
}
catch(Exception ex)
{
.....
}
return param1;
}
}
}
Обратите внимание, что это замедлит работу (у блокировки есть некоторые накладные расходы, и, в частности, у вас не будет двух потоков, выполняющих что-либо внутри блока блокировки одновременно), но это гарантирует, что Thread2, выполняющий этот метод, не сможет изменить что-то среднее между тем, когда Thread1 проверил значение и когда он попытается использовать результат этого теста, чтобы что-то сделать. Также не требуется .net 4, так что вы сможете его использовать.
edit - Стоит также упомянуть, что если у вас есть какие-либо другие методы, модифицирующие любой словарь, вы захотите заблокировать их таким же образом. Ключевым моментом здесь является то, что только один поток может возиться с вещами в любой момент времени.