Я тестирую устаревший код с Microsoft Fakes и некоторыми прокладками. Чтобы проверить параллелизм при доступе к общему ресурсу, мне пришлось создать несколько доменов приложений, которым я передал фикстуру с их контекстом. Этого нельзя было сделать только с потоками, потому что прокладки не являются потокобезопасными. Я также ожидаю, что при возврате этого контекста в основной домен приложения я смогу использовать эти данные для ожиданий тестов.
Одним из свойств моего приспособления является словарь, который я обновляю внутри своих прокладок для устаревшего кода. У меня проблема в том, что я не могу обновить значение словаря.
В этом методе я создаю статический класс, который записывает в реестр:
public static void ShimRegistry(PlafondManagerTestFixtureUser fixture)
{
Common.Util.Fakes.ShimRegistryHelper.SetLocalMachineRegistrySettingStringStringString = (parent, key, value) => {
if (fixture.Registries != null)
{
var quant = Decrypt(value);
if (fixture.Registries.ContainsKey(key))
fixture.Registries[key] = quant;
else
fixture.Registries.Add(key, quant);
}
return null;
};
Common.Util.Fakes.ShimRegistryHelper.GetLocalMachineRegistrySettingStringStringString = (parent, key, value) => {
string val;
fixture.Registries.TryGetValue(key, out val);
return Encrypt(val);
};
}
Когда я отлаживаю это, я вижу, что перед
fixture.Registries[key] = quant;
у меня есть «0» в качестве значения записи словаря и «2» в quant
. Сразу после запуска этой строки запись словаря по-прежнему читается как «0».
Я застрял с этим, и я не мог найти подобные проблемы с переполнением стека (или, может быть, я не нахожу правильных слов, чтобы описать это).
Другие части этой установки работают нормально. Я могу получить обновленную строку в основном потоке, поэтому я сомневаюсь, что это как-то связано с тем, что я делюсь экземплярами между AppDomains.
Может ли кто-нибудь помочь мне найти, что не так?
Обновлено: как предложил Джон Скит, я проверил это вне контекста mstest, appdomain, shims и даже прямо перед ошибочным кодом. В каждом случае он работает так, как ожидалось, так что это может иметь какое-то отношение к совместному использованию словаря между AppDomains в приспособлении.
Это то, что я использовал для тестирования:
Dictionary<string, string> test = new Dictionary<string, string>
{
{ "Key", "Value" }
};
test["Key"] = "Value2";
У меня такое чувство, что я пропускаю какую-то глупую мелочь, но никак не могу найти, что это такое.
Обновление 2: удалось сократить проблему до передачи словаря в другой домен приложения.
Вот пример консольного проекта, который я разместил на Github;
Обновление 3: Теперь, когда у меня было что-то более конкретное для поиска, я нашел этот ответ, который мне помог: Adam Ralph's ответ на вопрос "Обмен данными между доменами приложений"
Я сделаю ставку на сериализацию в строку, поскольку у меня уже есть способ сделать это легко, но все же хотелось бы понять, почему это происходит именно так.