Почему моя служба WCF возвращает FaultException, время ожидания после 10 вызовов? - PullRequest
8 голосов
/ 12 июня 2009

У меня есть служба WCF, которая иногда должна возвращать ошибку. По какой-то причине звонки в мой сервис начинают зависать со следующей ошибкой: «Канал запроса истек во время ожидания ответа после 00: 00: 59.8906201. Увеличьте значение тайм-аута, переданное на вызов Request, или увеличьте значение SendTimeout в Binding. Время, выделенное для этой операции, могло быть более длительный тайм-аут. "

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

public string GetData(int value)
{
    throw new FaultException("A testerror occured");
}

И тест-клиент:

   protected void RunTestGetData()
    {
        using (TestServiceReference.Service1Client client
            = new WSPerformanceTester.TestServiceReference.Service1Client())
        {
            try
            {
                client.GetData(1);
                client.Close();
                outputWriter.WriteLine(string.Format("Call run in thread {0}: GetData()", Thread.CurrentThread.ManagedThreadId));
                outputWriter.Flush();
            }
            catch (Exception e)
            {
                client.Abort();
                client.Close();
                outputWriter.WriteLine(string.Format("Error occured in thread {0}: GetData(): {1}", Thread.CurrentThread.ManagedThreadId, e.Message));
                outputWriter.Flush();
            }
        }
    }

Это происходит только тогда, когда служба возвращает FaultException. Если я выброшу обычное исключение, служба сможет продолжить работу после 10-го вызова. Очевидно, что я хотел бы красиво обернуть свои исключения, так что просто бросить нормальные исключения - не реальный вариант.

Почему я испытываю эти исключения тайм-аута? Заранее спасибо за любую помощь ..

Ответы [ 6 ]

3 голосов
/ 12 июня 2009

У меня недостаточно очков, чтобы комментировать, поэтому новый ответ ...

Службы собственного размещения допускают не более 10 одновременных подключений - независимо от транспорта. Если вы используете службы WCF внутри IIS / WAS, вам не нужно об этом беспокоиться (если только вы не используете XP / Vista, где максимальное число одновременных подключений равно 10).

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

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

Даже когда вы возвращаете ошибку, вам все равно нужно прервать () соединение. Кроме того, под ним находятся неуправляемые ресурсы, поэтому обязательно внедрите IDisposable в вызывающих клиентах / прокси.

2 голосов
/ 06 ноября 2009

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

WebServiceClient svcClient = new WebServiceClient();

string returnValue = svcClient.GetDocumentName(fileId);

svcClient.Close();

правильный шаблон:

using(WebServiceClient svcClient = new WebServiceClient())
{
   return svcClient.GetDocumentName(fileId);
}

ClientBase реализует IDisposable, который вызывает Close() в методе Dispose.

2 голосов
/ 12 июня 2009

Я думаю, это может быть связано с тем, что поведение службы WCF по умолчанию - 10 одновременных сеансов. Вы оставляете соединения открытыми после возникновения FaultExceptions? Вы можете попытаться изменить это значение в BehaviorConfiguration (ServiceThrottling> MaxConcurrentSessions) и посмотреть, изменит ли это что-либо. Я предлагаю вам использовать редактор настроек службы Microsoft, чтобы проверить, какие другие значения установлены по умолчанию. ( MSDN )

надеюсь, это поможет ...

1 голос
/ 18 июня 2009

Видимо, код клиента должен быть следующим:

protected void RunTestGetData()
{
    TestServiceReference.Service1Client client
        = new WSPerformanceTester.TestServiceReference.Service1Client()
    try
    {
        client.GetData(1);
    }
    catch (FaultException e)
    {
        //Handle fault
    }
    try
    {
        if (client.State != System.ServiceModel.CommunicationState.Faulted)
        {
            client.Close();
        }
    }
    catch(Exception e)
    {
        outputWriter.WriteLine("Error occured in Client.Close()");
        outputWriter.Flush();
        client.Abort();
    }
}

Вызов клиента. Аборт () всегда должен быть последним средством.

1 голос
/ 12 июня 2009

Я могу ошибаться, но я думаю, что это как-то связано с хостингом службы WCF.

Возможно, он не сможет своевременно ответить на запрос.

IIS в Windows XP, например, может отвечать на 5 (и я не очень уверен в этом сейчас) одновременных запросов. Если сделано больше запросов, он попадает в очередь.

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

0 голосов
/ 12 июня 2009

Попробуйте мой клиентский API-модель WCF Service Model и посмотрите, будут ли получены те же результаты. Я думаю, что-то не так в коде клиента ...

Код

PPT

Также включите подробное ведение журнала WCF на клиенте и сервере ...

...