обработка исключений для службы wcf - PullRequest
1 голос
/ 10 декабря 2011

В настоящее время я занимаюсь разработкой службы подписки на wcf.В моем приложении Windows Form есть кнопка «Подключиться», которая пытается подписаться на услугу.код выглядит следующим образом:

WSDualHttpBinding binding = (WSDualHttpBinding)client.Endpoint.Binding;
string clientcallbackaddress = binding.ClientBaseAddress.AbsoluteUri;
clientcallbackaddress += Guid.NewGuid().ToString();
binding.ClientBaseAddress = new Uri(clientcallbackaddress);

InstanceContext site = new InstanceContext(null, new mainForm(backgroundFormObject));
PostingContractClient client = new PostingContractClient(site);

client.Subscribe();
MessageBox.Show("Service has been connected!", "Connected");

Что касается обработки исключений, это то, что я сделал,

try
{
    //refer to codes above
}
catch (EndpointNotFoundException)
{
    MessageBox.Show("WCF Service has not been started.", "Error");
}
catch (CommunicationException)
{
    MessageBox.Show("Error");
}

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

Есть идеи, как это исправить?

Сообщение об ошибке

Объект связи, System.ServiceModel.Channels.ServiceChannel, не может использоваться длясвязь, потому что она находится в состоянии Failed.

Ответы [ 3 ]

3 голосов
/ 10 декабря 2011

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

Вам необходимо отследить любые ошибки, очистить и направить в сбойное состояние.

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

Возможно, канал находится в неисправном состоянии, поскольку у него истекло время ожидания.

        try
        {
              client.Subscribe();  
        }

        catch (Exception exception)
        {

            if (client != null)
            {
                client.Abort();
            }
            throw;
        }

        finally
        {
            if (client != null)
            {
                client.Close();
            }
        }
1 голос
/ 13 декабря 2011

Не уверен, что это то, что вы хотите, но из того, что я могу понять из вашего вопроса, это похоже на то, что вам нужно:

Поскольку вам необходимо, чтобы переменная была доступна в течение всего проекта, вы можете объявить InstanceContext и Client в начале класса.

InstanceContext site;
PostingContractClient client;

следовать в методе form_Load,

site = new InstanceContext(null, new mainForm(backgroundFormObject));
client = new PostingContractClient(site);

и, наконец, в вашей кнопке «Подключиться»,

        try
        {
            site = new InstanceContext(null, new mainForm(backgroundFormObject));
            var client = new PostingContractClient(site);

            WSDualHttpBinding binding = (WSDualHttpBinding)client.Endpoint.Binding;
            string clientcallbackaddress = binding.ClientBaseAddress.AbsoluteUri;
            clientcallbackaddress += Guid.NewGuid().ToString();
            binding.ClientBaseAddress = new Uri(clientcallbackaddress);

            client.Subscribe();
            MessageBox.Show("Service has been connected!", "Connected");
        }
        catch (EndpointNotFoundException)
        {
            if (client != null)
            {
                MessageBox.Show("WCF Service has not been started. Please try to manually connect again after the service has been started.", "Error");
1 голос
/ 13 декабря 2011

Я немного запутался в приведенном выше коде и пытаюсь объяснить это в комментариях:

// The client seems to be initialized by that time
WSDualHttpBinding binding = (WSDualHttpBinding)client.Endpoint.Binding;

...

// The client is initialized again
PostingContractClient client = new PostingContractClient(site);

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

var client = new Client();
client.Subscribe(); // you get an exception here
client.Subscribe(); // channel is faulted, as you got an exception accessing it the first time

Я мало работал с добавлением служб WCF в качестве ссылок, и я не знаю деталей реализации.Но, работая с совместным использованием сборок, я бы порекомендовал еще раз создать Client:

var client = new Client();
client.Subscribe(); // you get an exception here

client = new Client(); // I hope, another Channel is created, when calling the constructor.
client.Subscribe();

С уважением.

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