Istnieje określone zachowanie klasy Microsoft SqlDependency. Nawet jeśli wywołasz metodę SqlDependency.Stop(), zwolnij SqlCommand i SqlConnection — nadal utrzymuje grupy konwersacji (sys.conversation_groups) i punkty końcowe konwersacji (sys.conversation_endpoints) w bazie danych. Wygląda na to, że SQL Server ładuje każdy punkt końcowy konwersacji i wykorzystuje całą dozwoloną pamięć. tutaj testy, które to potwierdzają. Tak więc, aby wyczyścić wszystkie nieużywane punkty końcowe konwersacji i zwolnić całą zajętą pamięć, musisz uruchomić ten kod SQL dla swojej bazy danych:
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;
Ponadto SqlDependency nie daje możliwości otrzymywania WSZYSTKICH zmian tabeli. Tak więc nie otrzymasz powiadomienia o zmianach podczas ponownej subskrypcji SqlDependency.
Aby uniknąć tych wszystkich problemów, użyłem innej realizacji open source klasy SqlDependency - SqlDependencyEx . Używa wyzwalacza bazy danych i natywnego powiadomienia Service Broker do odbierania zdarzeń o zmianach w tabeli. Oto przykład użycia:
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);
Mam nadzieję, że to pomoże.