Det finns ett specifikt beteende i klassen Microsoft SqlDependency. Även om du anropar SqlDependency.Stop()-metoden, släpp SqlCommand och SqlConnection - den behåller fortfarande konversationsgrupper (sys.conversation_groups) och konversationsslutpunkter (sys.conversation_endpoints) i databasen. Det ser ut som att SQL Server laddar alla konversationsslutpunkter och använder allt tillåtet minne. Här tester som bevisar det. Så för att rensa alla oanvända konversationsslutpunkter och frigöra allt upptaget minne måste du starta den här SQL-koden för din databas:
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;
Dessutom ger SqlDependency dig inte en möjlighet att ta emot ALLA ändringar av tabellen. Så du får inget meddelande om ändringar under SqlDependency-prenumerationen.
För att undvika alla dessa problem hade jag använt en annan öppen källkodsförverkligande av SqlDependency-klassen - SqlDependencyEx . Den använder databasutlösare och inbyggd Service Broker-meddelande för att ta emot händelser om ändringar av tabellen. Detta är ett användningsexempel:
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);
Hoppas detta hjälper.