c # wcf - исключение при вызове open () для прокси-класса - PullRequest
3 голосов
/ 17 марта 2009

У меня следующая проблема, в основном у меня есть служба WCF, которая отлично работает в небольших тестах. Однако, когда я пытаюсь выполнить пакетный / загрузочный тест, я получаю InvalidOperationException с сообщением, когда метод open () вызывается для прокси-класса:

"Объект связи, System.ServiceModel.Channels.ServiceChannel, не может быть изменен, пока он находится в открытом состоянии."

Я искал в Google, но не могу найти никого, кто действительно цитирует это сообщение об исключении.

Я полагаю, что для диагностики может потребоваться дополнительная информация об услуге - когда служба получает данные одним из открытых методов, она в основном выполняет некоторую обработку и направляет данные в службу, связанную с данными (разные данные результат в другой маршрутизации). Чтобы служба работала как можно быстрее, каждый цикл приема, обработки и маршрутизации данных обрабатывается отдельным потоком в пуле потоков. Может ли это быть проблемой, возникающей из-за того, что один поток вызывает proxyClass.Open(), а другой уже использует его? Будет ли блок lock устранить эту проблему, если это действительно проблема?

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

=============================================== ==========================

Спасибо, что подчеркнули, что я не должен использовать конструкцию using для прокси-классов WCF. Тем не менее, статья MSDN не является наиболее четко написанным литературным произведением, поэтому один быстрый вопрос: должен ли я использовать прокси как таковой:

try
{
    client = new proxy.DataConnectorServiceClient();
    client.Open();
    //do work
    client.Close();
 }
 .................. //catch more specific exceptions
 catch(Exception e)
 {
    client.Abort();
 }

Ответы [ 4 ]

2 голосов
/ 17 марта 2009

Как вы используете прокси? Создание нового прокси-объекта для каждого звонка. Добавьте некоторый код относительно того, как вы используете прокси.

Желаемый способ использования прокси-сервера заключается в том, что для каждого вызова вы создаете новый прокси-сервер и распоряжаетесь им после завершения. Вы вызываете proxy.open () для открытого прокси, что неправильно. Он должен быть вызван только один раз.

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

if (proxy.State == CommunicationState.Faulted)
{
    proxy.Abort();
}
else
{
    try
    {
        proxy.Close();
    }
    catch
    {
        proxy.Abort();
    }
}

Зачем это делать? http://msdn.microsoft.com/en-us/library/aa355056.aspx

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

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

Также, если вы все еще хотите использовать удобство использования оператора, вы можете переопределить метод dispose в вашем прокси и удалить методом abort в случае ошибки wcf.

И не нужно вызывать .Open (), так как он открывается при необходимости с первым вызовом.

2 голосов
/ 14 января 2010

Я предполагаю, что вы используете .NET 3.5 или более позднюю версию. В .NET 3.5 класс WCF ClientBase'1 (базовый класс для сгенерированных клиентских прокси) был обновлен для использования кэшированных ChannelFactories / Channels. Следовательно, если только вы не используете одну из стратегий использования / создания клиента, которая отключает кэширование (конструктор клиента, который получает объект Binding, или доступ к одному из нескольких определенных свойств до создания резервного канала), даже если вы создаете новый экземпляр клиента, он вполне может использовать тот же канал. Другими словами, перед вызовом .Open () всегда проверяйте, проверяете ли вы статус .Created.

1 голос
/ 17 марта 2009

Похоже, что вы вызывали Open () несколько раз для одного и того же объекта.

0 голосов
/ 14 января 2010

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

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

Мы многому научились из этих постов в блоге:

http://blogs.msdn.com/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx

и

http://blogs.msdn.com/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspx

Надеюсь, это поможет и вам.

Приветствия, Вагнер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...