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);
プレ>これがお役に立てば幸いです。