Параллелизм

Пример параллелизма демонстрирует использование ServiceBehaviorAttributeConcurrencyMode перечисления, которое определяет, обрабатывает ли экземпляр службы сообщения последовательно или параллельно. Пример основан на начале работы, который реализует ICalculator контракт службы. Этот образец определяет новый контракт, ICalculatorConcurrency, унаследованный от ICalculator, который добавляет две операции для контроля состояния параллелизма службы. Изменив параметр параллелизма, можно запустить клиент и посмотреть, как изменилось поведение.

В этом образце клиентом является консольное приложение (EXE), а служба размещается в службах IIS.

Примечание.

Процедура настройки и инструкции по построению для данного образца приведены в конце этого раздела.

Доступны три режима параллелизма.

  • Single: все экземпляры службы обрабатывают в данный момент времени одно сообщение. Это режим параллелизма по умолчанию.

  • Multiple: каждый экземпляр службы обрабатывает несколько сообщений параллельно. Чтобы использовать этот режим параллелизма, реализация службы должна быть потокобезопасной.

  • Reentrant: каждый экземпляр службы одновременно обрабатывает одно сообщение, но принимает вызовы с повторным входом. Служба принимает эти вызовы только при вызове. Reentrant демонстрируется в примере ConcurrencyMode.Reentrant .

Использование параллелизма связано с режимом создания экземпляров. В режиме создания экземпляров PerCall параллелизм не имеет значения, так как каждое сообщение обрабатывается новым экземпляром службы. В режиме создания экземпляров Single имеет значение параллелизм Single или Multiple, в зависимости от того, обрабатывает ли один экземпляр сообщения последовательно или параллельно. В режиме создания экземпляров PerSession могут иметь значение любые режимы параллелизма.

Класс службы задает поведение параллелизма с помощью атрибута [ServiceBehavior(ConcurrencyMode=<setting>)], как показано в следующем образце кода. Преобразуя в комментарий различные строки, можно поэкспериментировать с режимами параллелизма Single и Multiple. Не забывайте строить службу заново после изменения режима параллелизма.

// Single allows a single message to be processed sequentially by each service instance.
//[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)]

// Multiple allows concurrent processing of multiple messages by a service instance.
// The service implementation should be thread-safe. This can be used to increase throughput.
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]

// Uses Thread.Sleep to vary the execution time of each operation.
public class CalculatorService : ICalculatorConcurrency
{
    int operationCount;

    public double Add(double n1, double n2)
    {
        operationCount++;
        System.Threading.Thread.Sleep(180);
        return n1 + n2;
    }

    public double Subtract(double n1, double n2)
    {
        operationCount++;
        System.Threading.Thread.Sleep(100);
        return n1 - n2;
    }

    public double Multiply(double n1, double n2)
    {
        operationCount++;
        System.Threading.Thread.Sleep(150);
        return n1 * n2;
    }

    public double Divide(double n1, double n2)
    {
        operationCount++;
        System.Threading.Thread.Sleep(120);
        return n1 / n2;
    }

    public string GetConcurrencyMode()
    {
        // Return the ConcurrencyMode of the service.
        ServiceHost host = (ServiceHost)OperationContext.Current.Host;
        ServiceBehaviorAttribute behavior = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
        return behavior.ConcurrencyMode.ToString();
    }

    public int GetOperationCount()
    {
        // Return the number of operations.
        return operationCount;
    }
}

По умолчанию образец использует параллелизм Multiple с режимом создания экземпляров Single. Код клиента изменен для использования асинхронного прокси. Это позволяет клиенту направлять службе сразу несколько вызовов, не дожидаясь ответа на каждый вызов. Можно наблюдать различия в поведении режима параллелизма службы.

При выполнении примера запросы и ответы операций отображаются в окне консоли клиента. Отображается режим параллелизма, в котором работает служба, вызываются все операции, и отображается число операций. Обратите внимание, что в режиме параллельности Multiple результаты возвращаются в порядке, отличном от порядка вызовов, потому что служба обрабатывает несколько сообщений параллельно. Если изменить режим параллельности на Single, результаты возвращаются в порядке вызова, потому что служба обрабатывает все сообщения последовательно. Чтобы закрыть клиент, нажмите клавишу ВВОД в окне клиента.

Настройка, сборка и выполнение образца

  1. Убедитесь, что вы выполнили процедуру однократной установки для примеров Windows Communication Foundation.

  2. Если вы используете Svcutil.exe для создания прокси-клиента, убедитесь, что этот параметр включен /async .

  3. Чтобы создать выпуск решения на языке C# или Visual Basic .NET, следуйте инструкциям в разделе Building the Windows Communication Foundation Samples.

  4. Чтобы запустить пример в конфигурации с одним или несколькими компьютерами, следуйте инструкциям в разделе "Примеры Windows Communication Foundation".