WCF "Экземпляр уже существует в CounterSet" при повторном открытии ServiceHost
У меня есть рабочий ServiceHost с одним NetTcpBinding и одной конечной точкой.
I .Close()
it. Затем я создаю новый экземпляр ServiceHost с той же конфигурацией, что и первый. Затем, когда я пытаюсь выполнить .Open()
новый экземпляр, я получаю это очень неудобное исключение:
System.ArgumentException occurred
Message=Instance '[email protected]:||localhost:2718|game|' already exists in CounterSet 'e829b6db-21ab-453b-83c9-d980ec708edd'.
Parameter name: InstanceName
Source=System.Core
ParamName=InstanceName
StackTrace:
at System.Diagnostics.PerformanceData.CounterSetInstance..ctor(CounterSet counterSetDefined, String instanceName)
Кто-нибудь видел это раньше? Это ошибка в .NET Framework (кстати, я использую 4.0)?
Вероятно, соответствующая информация о моем ServiceHost:
- Клиенты не подключены к хосту при первом закрытии;
- Пользовательский
IInstanceProvider
используется для создания экземпляров;
- Включена привязка
ReliableSession
;
- Тип службы помечен
ServiceBehavior
ниже;
.
[ServiceBehavior(
IncludeExceptionDetailInFaults = true,
InstanceContextMode=InstanceContextMode.PerSession,
ConcurrencyMode=ConcurrencyMode.Reentrant,
UseSynchronizationContext = false
)]
Я открыт для раскрытия дополнительной информации, которую вы, возможно, захотите узнать о приложении.
Обновление 1. Я скомпилировал приложение для таргетинга .NET 3.5, и ошибка не произошла. К сожалению, я должен деактивировать все, что было в Task
.
Обновление 2 Я зарегистрировал ошибку в Microsoft Connect об этой проблеме. Думаю, на этот вопрос уже ответили.
Ответы
Ответ 1
Это ошибка с .NET Framework 4.0. Я зарегистрировал ошибку в Microsoft Connect об этом.
Вот ответ от Microsoft:
Это похоже на известную проблему, вызванную по срочным вопросам в плотном закрытии/открытии последовательность ServiceHost. ServiceHost поддерживает некоторые счетчики производительности которые могут не получить сбор мусора приводя к этому исключению. Я предполагаю вы используете .Net Framework 4.0? Попробуйте обходным путем, сделав принудительный GC, прежде чем вы откроете второй ServiceHost:
GC.Collect()
GC.WaitForPendingFinalizers()
Выполнение того, что они посоветовали, решило проблему. Я надеюсь, что он будет исправлен в более позднем выпуске.
Ответ 2
Эта проблема не имеет отношения к самой службе WCF, но к System.ServiceModel.Diagnostics, которая позволяет контролировать службу с помощью счетчиков производительности. Он создает счетчик для каждого хоста службы и генерирует имя для параметра, заданного параметрами ServiceHost. И, если хост с одинаковыми параметрами уже существует - это вызовет это исключение. См. источники в Microsoft здесь (был найден GUID).
Это легко: просто отключите счетчики производительности для сервисов:
-
По app.config(проверено)
<configuration>
<system.serviceModel>
<diagnostics performanceCounters="Off" />
</system.serviceModel>
</configuration>
-
Во время выполнения (не проверено)
using System.Configuration;
using System.ServiceModel.Configuration;
using System.ServiceModel.Diagnostics;
Configuration config = ConfigurationManager.OpenExeConfiguration (ConfigurationUserLevel.None);
ServiceModelSectionGroup sg = ServiceModelSectionGroup.GetSectionGroup(config);
sg.Diagnostic.PerformanceCounters = PerformanceCounterScope.Off;
config.Save();
P.S. Я получил эту проблему на VS 2012,.Net 4.5 и VS 2010,.Net 4.0. Я думаю, это связано с конфигурацией программного обеспечения (VS?), Но я понятия не имею, к какому программному обеспечению и к какому параметру. У моих коллег нет такой проблемы, используя, в общем, ту же среду.