У нас есть консольное приложение С# (.Net 4.0), в котором "self hosts" используются две службы WCF: один используется WSHttpBinding
, а другой использует BasicHttpBinding
.
Подключаясь к этим сервисам, у нас есть два отдельных клиентских приложения: служба на основе Silverlight, которая использует BasicHttpBinding
, и другое консольное приложение, использующее WSHttpBinding
.
У приложения службы WCF обычно около 30 пользователей, подключенных через клиент Silverlight, и еще пару подключений от клиента консольного приложения. Он не "плоский" каким-либо образом; каждый клиент запрашивает службу WCF, возможно, один раз каждые 5 секунд.
Проблема заключается в том, что с перерывами приложение-служба перестает отвечать на запросы. Хотя сам сервер продолжает работать (он продолжает записывать в файл журнала), все действия WCF (на обоих ServiceHost
s) выглядят как "захватить". Новые запросы не обрабатываются (хотя TCP-соединения принимаются). Кроме того, количество потоков, потребляемых приложением, начинает резко увеличиваться со скоростью около одного нового потока в секунду. Сам код ничего не делает с Thread
или ThreadPool
s, хотя иногда он выдает Thread.Sleep
на несколько сотен миллисекунд.
К сожалению, проблема заключается в прерывистом характере проблемы: код регулярно работает в течение нескольких часов, даже дней без каких-либо проблем. Затем, без видимых причин, он внезапно перестает отвечать на запросы, и количество потоков начинает тикать.
Я пробовал имитировать активность пользователя - подключение и отключение клиентов, "обманывание" службы с помощью запросов, но я ничего не могу сделать, чтобы воспроизвести ошибку.
На всякий случай проблема была в WCF Throttling, я добавил этот код:
ServiceThrottlingBehavior throttlingBehavior = new System.ServiceModel.Description.ServiceThrottlingBehavior
{
MaxConcurrentCalls = 512,
MaxConcurrentInstances = 8192,
MaxConcurrentSessions = 8192
};
host.Description.Behaviors.Add(throttlingBehavior);
host2.Description.Behaviors.Add(throttlingBehavior);
.. без видимого эффекта.
Я поместил обширный журнал в код, чтобы попытаться определить, что это такое, что вызывает это поведение - протоколирование каждого вызова для каждого метода, но в результате ничего не появилось. Я завернул все в try
... catch
блокирует и плюет любые исключения в файл журнала, чтобы увидеть, что-то что-то упало где-то, а также захватили UnhandledException
аналогичным образом... но опять же, ничего не происходит неправильно.
Означает ли поведение, описанное выше, знакомое кому-либо, или может ли кто-нибудь предложить наилучший способ устранения этой проблемы?
EDIT: следуя рекомендациям Wal ниже, я захватил .DMP приложения, когда он начал ошибочно вести себя, и глядя на представление параллельных стеков в VS2012, я вижу:
... и другие очень похожи, но с различным количеством потоков. Я недостаточно умен, чтобы декодировать именно то, что это значит. Может ли кто-нибудь предложить, где начать смотреть дальше?