Има специфично поведение на класа Microsoft SqlDependency. Въпреки че извиквате метода SqlDependency.Stop(), освободете SqlCommand и SqlConnection - той все още поддържа групи за разговор (sys.conversation_groups) и крайни точки за разговор (sys.conversation_endpoints) в базата данни. Изглежда, че SQL Server зарежда всяка крайна точка на разговор и използва цялата разрешена памет. Тук тестове, които го доказват. И така, за да изчистите всички неизползвани крайни точки на разговор и да освободите цялата заета памет, трябва да стартирате този SQL код за вашата база данни:
DECLARE @ConvHandle uniqueidentifier
DECLARE Conv CURSOR FOR
SELECT CEP.conversation_handle FROM sys.conversation_endpoints CEP
WHERE CEP.state = 'DI' or CEP.state = 'CD'
OPEN Conv;
FETCH NEXT FROM Conv INTO @ConvHandle;
WHILE (@@FETCH_STATUS = 0) BEGIN
END CONVERSATION @ConvHandle WITH CLEANUP;
FETCH NEXT FROM Conv INTO @ConvHandle;
END
CLOSE Conv;
DEALLOCATE Conv;
Освен това SqlDependency не ви дава възможност да получавате ВСИЧКИ промени в таблицата. Така че не получавате известие за промени по време на повторен абонамент за SqlDependency.
За да избегна всички тези проблеми, използвах друга реализация с отворен код на клас SqlDependency - SqlDependencyEx . Той използва задействане на база данни и собствено известие на Service Broker, за да получава събития за промени в таблицата. Това е пример за употреба:
int changesReceived = 0;
using (SqlDependencyEx sqlDependency = new SqlDependencyEx(
TEST_CONNECTION_STRING, TEST_DATABASE_NAME, TEST_TABLE_NAME))
{
sqlDependency.TableChanged += (o, e) => changesReceived++;
sqlDependency.Start();
// Make table changes.
MakeTableInsertDeleteChanges(changesCount);
// Wait a little bit to receive all changes.
Thread.Sleep(1000);
}
Assert.AreEqual(changesCount, changesReceived);
Надявам се това да помогне.