Дуплекс WCF-сервис зависает на 11-м звонке - PullRequest
3 голосов
/ 17 июля 2009

У меня есть дуплексный сервис WCF, который зависает после магических 10 прокси-копий. Конкретная ошибка на клиенте:

"System.TimeoutException: эта операция запроса, отправленная на net.tcp: // localhost: 8080 / RoomService / netTcp, не получила ответ в течение настроенного времени ожидания (00: 00: 59.9960000)".

На сервере нет видимых сообщений об ошибках.

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

try
{
    client.Close();
}
catch (CommunicationException)
{
    client.Abort();
}
catch (TimeoutException)
{
    client.Abort();
}
catch (Exception)
{
    client.Abort();
    throw;
}

И я установил мое поведение регулирования на 500 одновременно:

ServiceThrottlingBehavior throttlingBehavior = new ServiceThrottlingBehavior()
{
    MaxConcurrentCalls = 500,
    MaxConcurrentSessions = 500,
    MaxConcurrentInstances = 500
};

Я установил для ConcurrencyMode моего сервиса значение Multiple и перепробовал все три возможных значения для InstanceContextMode.

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]

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

Я пробовал NetTcpBinding, WSDualHttpBinding и PollingDuplexBinding (в Silverlight) с одинаковыми результатами для каждого. Я не могу попробовать BasicHttpBinding или WSHttpBinding, так как это дуплексный сервис.

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

На клиенте я пытался использовать новые прокси для каждого теста и повторно использовать один и тот же прокси во всех тестах, но безуспешно. Я попытался создать новый InstanceContext для каждого прокси-сервера и повторно использовать один и тот же InstanceContext во всех прокси-серверах, и опять не повезло.

Что бы я ни делал, после 10-го теста, выполненного в моем тестовом жгуте, следующий вызов в сервис зависает.

Есть мысли о том, что я могу делать неправильно?

Ответы [ 5 ]

5 голосов
/ 17 июля 2009

ОК, поэтому я сделал по крайней мере одну глупую ошибку: я создавал поведение регулирования, но не хотел добавлять его в службу. Теперь добавлено правильно:

ServiceThrottlingBehavior throttlingBehavior = new ServiceThrottlingBehavior()
{
    MaxConcurrentCalls = 500,
    MaxConcurrentSessions = 500,
    MaxConcurrentInstances = 500
};
base.Description.Behaviors.Add(throttlingBehavior);

И теперь я могу запустить более 10 тестов, и, следовательно, моя непосредственная проблема решена.

Но я все еще озадачен, почему я вообще сталкиваюсь с этой проблемой, поскольку я специально закрываю один прокси, прежде чем перейти к следующему. MaxConcurrentXXX 2 должен работать в этом сценарии; Мне не нужно, чтобы MaxConcurrentXXX составлял 500. Я немного беспокоюсь о масштабируемости, если каждый клиент, подключающийся к серверу, продолжает проверять соединение даже после того, как он на самом деле подключен.

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

0 голосов
/ 25 сентября 2009

В начале использования функции Callback в клиенте OperationContext.Current.Channel.Close (); * +1001 *

Это решит проблему.

0 голосов
/ 18 июля 2009

Посмотрите на ServiceBehavior.AutomaticSessionShutdown.

0 голосов
/ 17 июля 2009

У меня нет ответа, но у меня есть несколько советов по отладке.

1) Подключите отладчик visual studio к процессу обслуживания и посмотрите, сможет ли он отлавливать происходящее.

2) Сконфигурируйте поведение службы для передачи клиенту информации об исключении и посмотрите, генерирует ли служба исключение, о котором не сообщается:

<behaviors>
    <serviceBehaviors>
        <behavior name="ServiceBehavior">
            <serviceDebug includeExceptionDetailInFaults="True"/>
        </behavior>
    </serviceBehaviors>
</behaviors>

3) Включите ведение журнала службы с включенным ActivityTracing и используйте средство просмотра трассировки служб (из Windows SDK ), чтобы проанализировать журнал и посмотреть, появляется ли что-нибудь

<system.diagnostics>
    <trace autoflush="true" />
    <sources>
        <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
            <listeners>
                <add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="Service.svclog"  />
            </listeners>
        </source>
    </sources>
</system.diagnostics>

4) Изолировать оболочку службы от функционального кода и посмотреть, не зависла ли служба. Если это не так, постепенно добавляйте функциональность обратно, пока вы не выясните, что заставляет его зависать

5) Если вы используете HTTP-привязку, прокси сервис с fiddler и регистрируйте трафик http.

6) Попробуйте Размещение службы WCF в управляемой службе Windows и подключите отладчик к процессу службы после его запуска.

0 голосов
/ 17 июля 2009

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

Не освобождаются ли какие-либо серверные ресурсы или блокировки должным образом? Поскольку ваш экземпляр службы для каждого сеанса, я подозреваю, что объект сервера висит и держит блокировку. Что если вы измените поведение на вызов?

...