"Handle ist ungültig" Fehler beim Öffnen von SqlConnection

10

Dieser Fehler tritt sporadisch und unerklärlicherweise auf, insbesondere beim Herstellen einer Verbindung mit unserer Sitzungsstatusdatenbank. Hier ist der Fehler:

%Vor%

Im Windows-Ereignis-Viewer erscheint manchmal ein möglicher Fehler:

%Vor%

EDIT: ein anderer Geschmack der Ausnahme ist wie folgt:

%Vor%

Kann jemand vorschlagen:

  1. Was bedeutet das?
  2. Was könnte das verursachen (dies ist in einer Anwendung, die seit langer Zeit sehr stabil läuft, ohne dass große Infrastrukturänderungen vor dem Erscheinen dieser Infrastruktur stattgefunden haben)?
  3. Was könnte getan werden, um es zu lösen?
ChaseMedallion 01.07.2015, 17:32
quelle

2 Antworten

8

Wie sich herausstellte, haben wir den Fehler bis zur Deserialisierung eines CancellationToken mit Json.Net verfolgt.

Das zugrunde liegende Problem tritt auf, wenn Code immer noch versucht, ein OS-Handle zu verwenden, das freigegeben wurde. Dies kann natürlich passieren, wenn Ihr Code direkt mit Handles arbeitet. Unser Code tut das nicht, aber es stellt sich heraus, dass dies mit Json.Net passieren kann. Hier ist wie:

Wir hatten eine Klasse wie folgt:

%Vor%

Das Problem trat auf, als jemand MyClass vom Typ CancellationToken eine Eigenschaft hinzufügte:

%Vor%

Hier ist das Problem. Wenn es serialisiert wird, sieht ein CancellationToken wie folgt aus:

%Vor%

Beachten Sie, dass die Ausführung der WaitHandle-Eigenschaft des Tokens und das Serialisieren des Werts des zugrunde liegenden Betriebssystem-Handles (1508) dazu führt, dass dies "faul" ist.

Wenn wir das Token deserialisieren, startet Json.Net mit new CancellationToken() (entspricht CancellationToken.None ). Anschließend wird die Handle -Eigenschaft des WaitHandle dieses Tokens mit dem gespeicherten IntPtr -Wert ausgefüllt. Ein offensichtlicher Weg, auf dem dies schief geht, ist, dass das WaitHandle des Standard-CancellationTokens jetzt auf ein wahrscheinliches ungültiges Handle zeigt. Das größere Problem ist jedoch, dass das Aktualisieren des Handles das ursprüngliche SafeHandle von WaitHandle dereferenziert, sodass der Garbage Collector seinen Finalizer ausführen und ihn bereinigen kann. Sie können dann Opfer der folgenden Reihe von Ereignissen werden:

  1. Handle 123 ist einer gepoolten Datenbankverbindung zugeordnet
  2. Eine Deserialisierung weist Handle 123 dem WaitHandle
  3. des Standard-Abbruch-Tokens zu
  4. Eine zweite Deserialisierung weist dem WaitHandle
  5. des Standard-Abbruch-Tokens einen neuen Handle-Wert zu
  6. Der Garbage Collector führt den freigegebenen sicheren Handle-Wert 123 aus und finalisiert ihn.
  7. Die Datenbankverbindung zeigt jetzt auf ein ungültiges Handle

Hier ist ein Code, der das Problem mit einem FileStream :

absichtlich repliziert %Vor%     
ChaseMedallion 07.07.2015, 19:39
quelle
0

Sie könnten versuchen, in den SQL Server-Konfigurationsmanager zu wechseln und ein oder mehrere Protokolle zu deaktivieren, um zu sehen, ob das hilft. Wenn der SQL Server und der Client sich auf demselben Computer befinden, verwenden Sie möglicherweise gemeinsam genutzten Speicher, und das System hat den Heapspeicher für Handles erschöpft. Versuchen Sie, Verbindungen zu zwingen, TCP zu verwenden, und sehen Sie, ob Sie das gleiche Problem bekommen.

    
Wonko 01.07.2015 18:30
quelle

Tags und Links