Поделиться через


One-Way

В примере Oneway показана реализация однонаправленных операций службы. Клиент не ожидает завершения операций службы, в отличие от двусторонних операций службы. Этот пример основан на начале работы и использует привязку wsHttpBinding. Служба в этом примере — это локальное консольное приложение, позволяющее наблюдать за службой, получающей и обрабатывающей запросы. Клиент также является консольным приложением.

Замечание

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

Чтобы создать односторонний контракт службы, определите контракт службы, примените OperationContractAttribute класс к каждой операции и задайте IsOneWay значение true , как показано в следующем примере кода:

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOneWayCalculator
{
    [OperationContract(IsOneWay=true)]
    void Add(double n1, double n2);
    [OperationContract(IsOneWay = true)]
    void Subtract(double n1, double n2);
    [OperationContract(IsOneWay = true)]
    void Multiply(double n1, double n2);
    [OperationContract(IsOneWay = true)]
    void Divide(double n1, double n2);
}

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

// This service class implements the service contract.
// This code writes output to the console window.
 [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
    InstanceContextMode = InstanceContextMode.PerCall)]
public class CalculatorService : IOneWayCalculator
{
    public void Add(double n1, double n2)
    {
        Console.WriteLine("Received Add({0},{1}) - sleeping", n1, n2);
        System.Threading.Thread.Sleep(1000 * 5);
        double result = n1 + n2;
        Console.WriteLine("Processing Add({0},{1}) - result: {2}", n1, n2, result);
    }
    ...
}

Когда клиент вызывает службу, вызов возвращается без ожидания завершения операции службы.

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

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

Add(100,15.99)
Subtract(145,76.54)
Multiply(9,81.25)
Divide(22,7)

Press <ENTER> to terminate client.

Показаны следующие выходные данные службы:

The service is ready.
Press <ENTER> to terminate service.

Received Add(100,15.99) - sleeping
Received Subtract(145,76.54) - sleeping
Received Multiply(9,81.25) - sleeping
Received Divide(22,7) - sleeping
Processing Add(100,15.99) - result: 115.99
Processing Subtract(145,76.54) - result: 68.46
Processing Multiply(9,81.25) - result: 731.25
Processing Divide(22,7) - result: 3.14285714285714

Замечание

ПРОТОКОЛ HTTP, по определению, протокол запроса и ответа; При выполнении запроса возвращается ответ. Это верно даже для односторонней операции службы, выполняемой по протоколу HTTP. При вызове операции служба возвращает код состояния HTTP 202 до выполнения операции службы. Этот код состояния означает, что запрос был принят для обработки, но обработка еще не завершена. Клиент блокирует операцию, пока не получит ответ 202 от службы. Это может привести к непредвиденному поведению при отправке нескольких односторонних сообщений через привязку, настроенную для использования сеансов. Привязка, используемая wsHttpBinding в этом примере, настроена на использование сеансов по умолчанию для установления контекста безопасности. По умолчанию сообщения в сеансе гарантированно прибывают в том порядке, в котором они отправляются. Из-за этого при отправке второго сообщения в сеансе он не обрабатывается до тех пор, пока первое сообщение не будет обработано. Результатом этого является то, что клиент не получает ответ 202 для сообщения до завершения обработки предыдущего сообщения. Таким образом, клиент, кажется, блокирует каждый следующий вызов операции. Чтобы избежать этого поведения, этот пример настраивает среду выполнения для одновременной отправки сообщений в отдельные экземпляры для обработки. Пример задает значение InstanceContextModePerCall , чтобы каждое сообщение можно было обрабатывать разными экземплярами. ConcurrencyMode установлен с Multiple, чтобы разрешить нескольким потокам отправлять сообщения одновременно.

Настройка, сборка и запуск примера

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

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

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

Замечание

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