WCF - создать новый канал для каждого вызова - почему этот код не работает? - PullRequest
3 голосов
/ 14 июня 2011

Я экспериментирую с асинхронными вызовами WCF.Я пытаюсь сделать несколько звонков на одну и ту же услугу.

С клиента я создаю новый канал для каждого звонка, выполняю звонок (назначая ему метод обратного вызова), а затем в обратном вызове закрываюchannel.

В сервисе я добавил вызов thread.sleep, чтобы имитировать работу сервиса.

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

Не удалось подключиться к net.tcp: // localhost: 61501 / Calulator.Попытка подключения продолжалась в течение промежутка времени 00: 00: 02.9332933.Код ошибки TCP 10061: не удалось установить соединение, потому что целевая машина активно отказала ему 127.0.0.1:61501.

Итак, у меня есть пара вопросов:

  1. AmПравильно ли открывать новый канал для каждого звонка?
  2. Что вызывает это исключение?

Большое спасибо заранее за любую помощь.

Мой код выглядит следующим образом, его также можно найти здесь: https://subversion.assembla.com/svn/agilenet/tags/WcfStackOverflow/Wcf

Служба:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace Service
{
    class Program
    {
        static void Main(string[] args)
        {
            NetTcpBinding netBinding = new NetTcpBinding();

            ServiceHost host = null;
            host = new ServiceHost(
                    typeof(Calculator),
                    new Uri("net.tcp://localhost:61501/Calulator"));
            host.AddServiceEndpoint(
                    typeof(ICalculator),
                    netBinding,
                    string.Empty);
            host.Open();

            Console.ReadLine();
        }
    }

    [ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        int Add(int value1, int value2);

        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginAdd(int value1, int value2, AsyncCallback callback, object state);

        int EndAdd(IAsyncResult result);
    }

    public class Calculator : ICalculator
    {
        public int Add(int value1, int value2)
        {
            Console.WriteLine(
                "Incoming Add request {0}, {1}",
                value1.ToString(),
                value2.ToString());
            System.Threading.Thread.Sleep(500);
            return value1 + value2;
        }

        public IAsyncResult BeginAdd(int value1, int value2, AsyncCallback callback, object state)
        {
            throw new NotImplementedException();
        }

        public int EndAdd(IAsyncResult result)
        {
            throw new NotImplementedException();
        }

    }
}

Клиент:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Service;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {

            NetTcpBinding netBinding = new NetTcpBinding();
            ChannelFactory<ICalculator> factory = new ChannelFactory<ICalculator>(
                netBinding,
                "net.tcp://localhost:61501/Calulator");

            for (int i = 0; i < 100; i++)
            {
                ICalculator service = factory.CreateChannel();
                service.BeginAdd(i, 0, SaveCallback, service);
            }

            Console.ReadLine();
        }

        static void SaveCallback(IAsyncResult ar)
        {
            ICalculator service = (ICalculator)ar.AsyncState;
            Console.WriteLine(service.EndAdd(ar).ToString());
            ((IContextChannel)service).Close();

        }

    }

}

1 Ответ

1 голос
/ 14 июня 2011

Я думаю, что вы столкнулись с пределом TCP-соединения для Windows (7 / Vista / XP).Эти ОС ограничивают количество (входящих) tcp-соединений до 20. Поиск в Google «предела windows tcp-соединения» дает вам гораздо больше информации о предмете.

В SuperUser также есть тема на эту тему: https://superuser.com/questions/253141/inbound-tcp-connection-limit-in-windows-7. Дополнительная информация также в ServerFault (по ссылке из SU).

Итак, чтобы ответить на ваш вопрос:

  1. Нет, вы не должны открывать новыеканал для каждого вызова.
  2. Вы достигли предела несерверной версии Windows (вероятно, 7 или Vista, потому что вы можете получить 20 подключений).Вы получаете случайное количество успешных соединений, потому что иногда ОС достаточно быстра, чтобы очистить несколько первых соединений, но частота запросов настолько высока, что вы в конечном итоге достигнете максимума.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...