Методы WCF, разделяющие словарь - PullRequest
2 голосов
/ 19 октября 2011

Я создаю сервисную библиотеку WCF, и у меня есть вопрос о безопасности потоков, потребляющих метод внутри этой библиотеки, вот полная реализация, которая у меня есть до сих пор.

namespace WCFConfiguration
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
    public class ConfigurationService : IConfigurationService
    {
        ConcurrentDictionary<Tuple<string,string>, string> configurationDictionary = new ConcurrentDictionary<Tuple<string,string>, string>();

        public void Configuration(IEnumerable<Configuration> configurationSet)
        {
            Tuple<string, string> lookupStrings;
            foreach (var config in configurationSet)
            {
                lookupStrings = new Tuple<string, string>(config.BoxType, config.Size);
                configurationDictionary.TryAdd(lookupStrings, config.RowNumber);
            }
        }

        public void ScanReceived(string boxType, string size, string packerId = null)
        {

        }
    }
}

Представьте, что яу меня есть 10 значений в моем configurationDictionary, и многие люди хотят запросить этот словарь, использующий метод ScanReceived. Являются ли эти 10 значений общими для каждого из клиентов, которые запрашивают ScanReceived?Нужно ли мне изменить мой ServiceBehavior?

Кстати, метод конфигурации используется только одним человеком.

1 Ответ

1 голос
/ 19 октября 2011

С InstanceContextMode из PerCall вы должны получать новый экземпляр вашей службы и ваш словарь каждый раз, когда поступает удаленный вызов (который, я предполагаю, будет либо Configuration(), либо ScanReceived()).Это не будет разделять configurationDictionary между несколькими клиентами.

С ConcurrencyMode из Single у вас когда-либо будет только один поток, выполняющий ваш код в любой момент времени.Так что любые проблемы параллелизма спорны.

Два способа поделиться configurationDictionary:

  1. Сделать это статичным: private readonly static ConcurrentDictionary<...> ...
  2. Изменить свой InstanceContextMode,и, возможно, ваш ConcurrencyMode.

Я бы порекомендовал первый вариант, если вы не ожидаете тысячи вызовов в службу в секунду.

MSDN имеет некоторую информацию о InstanceContextMode и создание классов обслуживания.


Если вы переключитесь на InstanceContextMode.Single и ConcurrencyMode.Multiple, вы можете получить множество потоков, выполняющихся одновременно, и вам потребуетсябеспокоиться о синхронизированном доступе.

Главное, на что нужно обратить внимание, это то, что, когда вы запрашиваете / просматриваете свой словарь, кто-то другой может изменить его.Получение снимка словаря и последующий запрос снимка должны обойти эту проблему:

foreach (var x in configurationDictionary.ToArray())
{
     ....
}

Или, если вы используете LINQ:

var someResult = configurationDictionary.ToArray().Where(...).Select(...)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...