ConcurrencyMode.Multiple в службах WCF без сохранения состояния - PullRequest
0 голосов
/ 23 декабря 2010

В настоящее время у нас есть несколько служб WCF, которые используют значение по умолчанию ServiceBehavior.Из-за проблем с масштабируемостью мы рассматриваем применение атрибута ConcurrencyMode = ConcurrencyMode.Multiple для повышения пропускной способности.Все наши сервисные вызовы не имеют состояния, например:

PersonService.cs:

public class PersonService : IPersonService
{
  public GetPersonResponse GetPerson(GetPersonRequest request)
  {
    GetPersonResponse response = new GetPersonResponse();

    try
    {
      response.Person = Person.GetPerson(request.PersonID);

      return response;
    }
    catch (Exception ex)
    {
      return (GetPersonResponse) response.SetException(ex);
    }
  }
}

Person.cs:

public static class Person
{
  public static PersonDataContract GetPerson(int personID)
  {
    PersonDataContract pdc = null;

    // load contract from db...
    pdc = Database.Load<PersonDataContract>(personID);

    // Address is another static class in the same pattern as Person
    pdc.Addresses = Address.GetAddressesForPerson(personID);

    return pdc;
  }
}

Все методы в Person классы являются статическими для повышения производительности и не сохраняют состояния для безопасности потоков.Класс Database также является статическим, но его методы ссылаются на статические переменные.

В этом контексте, что необходимо сделать поточно-ориентированным, чтобы ConcurrencyMode.Multiple не вызывал проблем с многопоточностью?Я имею в виду только класс Database, но нужно ли также блокировать класс Person (и все другие классы, которые следуют той же схеме)?

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

Ответы [ 2 ]

4 голосов
/ 23 декабря 2010

Если вы используете механизм активации «по вызову» по умолчанию (который прекрасно работает, если ваши сервисы полностью не сохраняют состояние), нет абсолютно никакого смысла добавлять ConcurrencyMode.Multiple, так как каждый входящий запрос получит свой собственный экземпляр класса сервиса для обработать его запрос. Это предпочтительный и рекомендуемый параметр для InstanceContextMode.

Узнайте больше об управлении экземплярами в WCF в журнале MSDN: Откройте для себя мощные методы управления экземплярами для разработки приложений WCF

Единственный раз, когда вы получаете выгоду от использования ConcurrencyMode.Multiple, это когда у вас есть одноэлементная служба WCF - но это крайне нежелательно, так как это а) большое препятствие для масштабируемости и б) чрезвычайно сложно правильно программировать.

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

2 голосов
/ 03 июля 2016

Если ваша служба не имеет состояния и поточно-ориентирована, лучше использовать InstanceContextMode.Single в сочетании с ConcurrencyMode.Multiple.

Это позволит избежать создания экземпляров службы, уменьшить объем памяти, уменьшить активность GC.

Почти все услуги, которые я разрабатываю, выполняются таким образом ...

Если бы не было необходимости хранить отдельные экземпляры для вызова или сеанса, я бы получил его.

В других ответах упоминается «служба Singleton WCF - но это крайне нежелательно, так как это а) большое препятствие для масштабируемости и б) чрезвычайно сложно правильно программировать».

Это НЕ очень обескураживает, не имеетвлияние на масштабируемость (на самом деле может быть полезным), и в этом нет ничего хитрого.

...