В настоящее время я столкнулся с проблемой, которую я не понимаю. У меня есть wcf-клиент, который вызывает службу wcf через несколько потоков одновременно (как на одном компьютере). Иногда я встречаюсь с известным System.ServiceModel.CommunicationException
"Произошла ошибка при получении ответа HTTP на xxx.Это может быть связано с привязкой конечной точки службы, не использующей протокол HTTP. Это также может быть связано с тем, что сервер HTTP-запроса прерывается (возможно, из-за закрытия службы). Подробнее см. в журналах сервера." ,
иногда это работает. Кажется совершенно случайным, если вызов службы завершается успешно.
Запрос очень мал, его просто вызов (int, bool, enum). Запрос содержит ок. 300-500 КБ записей из базы данных MSSQL.
Я искал сотни на сайтах для решения, увеличивал значения тайм-аута, значения буфера, значения размера запроса и ответа на стороне клиента и службы. Я добавил, что атрибуты [DataContract] и [DataMember] отсутствовали. И все равно изменений нет.
Я активировал полное отслеживание, просто чтобы увидеть очень странное поведение:
Звонки с клиента останавливаются локально с данным исключением, но сервер обрабатывает их и отправляет ответ, который никогда не доходит до клиента. Проверьте время на данной трассе - клиент прерывается, сервер продолжает.
В трассировке я вижу тяжелый, как на этом графике:
Пожалуйста, помогите остановить бесконечный поиск?
Обновление 1:
Я загрузил клиент и сервер config, возможно, это помогает.
Обновление 2:
Мы включили параметр конфигурации для ConnectionLimit (connection = 80), как это было предложено Yahia. В настоящее время кажется, что это решило проблему, но мы по-прежнему пытаемся воспроизвести ошибку.
Обновление 3:
Блин. Через три часа я снова вижу такое же поведение... У нас было другое предложение: как вы можете видеть, мы используем quartz.net в клиенте, начиная с 20 потоков. Работы, выполняемые кварцевым двигателем, подключаются к нашему сервису. Теперь я пытаюсь представить, что произойдет, если, скажем, 7 потоков пытаются подключить службу в одно и то же время.
Обновление 4:
Мы установили параметры tcp в реестре, а также в config. После перезагрузки ничего не изменилось:(
Это были изменения реестра:
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters - TcpNumConnections = 65534
HKLM\System\CurrentControlSet\Services\Tcpip\Параметры - MaxUserPort = 65534
HKCU\Software\Microsoft\Windows\CurrentVersion\Настройки Интернета - MaxConnectionsPer1_0Server = 20
HKLM\Software\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER - iexplore.exe = 20
HKLM\Software\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER - MyClientsExeName.exe = 20
Обновление 5:
Обновление 6:
[DataContract]
public class Currency
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Code { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public ForeignNoteDetails ForeignNoteDetails { get; set; }
[DataMember]
public CurrencyRates Rates { get; set; }
[DataMember]
public PreciousMetallDetails PreciousMetallDetails { get; set; }
[DataMember]
public CurrencyType Type { get; set; }
}
[DataContract]
public class ForeignNoteDetails
{
[DataMember]
public double CardholderBillingCurrencyCode { get; set; }
[DataMember]
public string Country { get; set; }
[DataMember]
public string CountryCode { get; set; }
[DataMember]
public int CurrencyUnit { get; set; }
[DataMember]
public List<string> Notes { get; set; }
}
[DataContract]
public class CurrencyRates
{
[DataMember]
public ExchangeRate PurchaseRate { get; set; }
[DataMember]
public ExchangeRate SellRate { get; set; }
}
[DataContract]
public class PreciousMetallDetails
{
[DataMember]
public string PreciousMetalType { get; set; }
[DataMember]
public double Fineness { get; set; }
}
Вызов службы:
protected IEnumerable<Currency> GetCurrencyLevel(int id, bool netRate = true, RatesCalculationSource ratesSource = RatesCalculationSource.ReutersRates)
{
return this.calculationClient.GetCurrencyLevel(new RatesCalculationSetting() { CalculationLevelId = id, CalculateGrossRates = !netRate, Soruce = ratesSource });
}
Создание клиента:
protected ICalculationServiceClientService calculationClient = IoC.DependencyManager.Resolve<ICalculationServiceClientService>();
Другой вызов службы (работы):
this.calculationClient.DistributeTradingOfficeRatesLevels(branchOfficeLevelId, tradingLevelId);
Если это определено как
void DistributeTradingOfficeRatesLevels(int branchOfficeRatesLevelId, int tradingOfficeRatesLevelId)
Обновление 7: