SqlDependency-Fehler nach langer Zeit

8

Ich habe einen Windows-Dienst bekommen, der Einfügungen in einer Tabelle mit der SqlDependency-Klasse abhört.

Es funktioniert für mehrere Tage, aber dann hört plötzlich auf zu arbeiten.

Im normalen Szenario erhalte ich Änderungsereignisse

  
    

e.Type = SqlNotificationType. Ändern
    e.Info = SqlNotificationInfo. Einfügen
    e.Source = SqlNotificationSource. Daten

  

Wenn sich nichts ändert, erhalte ich alle 3600 Sekunden ein Timeout-Ereignis

  
    

e.Type = SqlNotificationType. Ändern
    e.Info = SqlNotificationInfo. Fehler
    e.Source = SqlNotificationSource. Zeitüberschreitung

  

oder (weiß nicht, warum zwei verschiedene Timeout-Ereignisse vorliegen)

  
    

e.Type = SqlNotificationType. Ändern
    e.Info = SqlNotificationInfo. Unbekannt
    e.Source = SqlNotificationSource. Zeitüberschreitung

  

Dies kann für eine Woche oder länger funktionieren, aber plötzlich erhalte ich keine Änderungsereignisse mehr und erhalte stattdessen alle 60 Sekunden ein Ereignis mit

  
    

e.Type = SqlNotificationType. Ändern
    e.Info = SqlNotificationInfo. Fehler
    e.Source = SqlNotificationSource. Client

  

Die msdn-Dokumentation für SqlNotificationSource.Client sagt

  
    

Eine vom Client initiierte Benachrichtigung ist aufgetreten, z. B. ein clientseitiges Timeout oder ein Versuch, einen Befehl zu einer Abhängigkeit hinzuzufügen, die bereits ausgelöst wurde.

  

Ich denke, das bedeutet, dass beim Erstellen der Abhängigkeit ein Zeitlimit aufgetreten ist.

Derselbe Code läuft die ganze Zeit und sieht so aus:

%Vor%

Wenn ich meinen Dienst neu starte, funktioniert es wieder gut.

Ich habe einige Nachforschungen angestellt und herausgefunden, dass die Fehler nach einem geplanten Backup auf dem Server zu starten scheinen (was jeden Tag passiert). Habe eine andere Anwendung wo ich um die selbe Zeit Fehler bekomme wie

  
    

Beim Empfangen von Ergebnissen vom Server ist ein Transportfehler aufgetreten. (Anbieter: TCP-Provider, Fehler: 0 - Die Semaphor-Zeitüberschreitung ist abgelaufen.)

  

Meine ursprüngliche Vermutung war, dass SqlDependency.Start() eine Verbindung zum Server herstellt, die während der geplanten Sicherung fehlschlägt und nie wiederhergestellt wird. Aber die erste Zeile in der msdn Dokumentation sagt

  
    

Der SqlDependency-Listener wird neu gestartet, wenn in der SQL Server-Verbindung ein Fehler auftritt.

  

Irgendwelche Ideen, wie Sie das lösen können?
(Ich kann natürlich den Dienst fehlschlagen lassen und den Dienst-Manager neu starten lassen. Das Problem ist, dass der Dienst auch andere Dinge tut, die ordnungsgemäß beendet werden müssen, so dass ich nicht einfach Enviroment.Exit (-1) aus dem tun kann Ereignishandler)

    
adrianm 11.03.2014, 08:09
quelle

1 Antwort

9

Finde die Ursache und eine Lösung.

Zuerst habe ich herausgefunden, dass die Zeile

ist
  
    

Der SqlDependency-Listener wird neu gestartet, wenn in der SQL Server-Verbindung ein Fehler auftritt.

  

ist nur in der .Net 4 -Dokumentation vorhanden.

Einige Tests zeigen, dass es sich nicht nur um eine Änderung in der Dokumentation handelt! Das Client / Fehler-Ereignis wird nicht angezeigt, wenn mit CLR4 ausgeführt wird.

Die Ursache ist also ein Verbindungsfehler, der innerhalb der SqlDependency in .Net 4 behandelt wird, aber nicht in früheren Versionen.

In .Net 2-3.5 ist es möglich, nach dem Fehler mit einem SqlDependency.Stop() / SqlDependency.Start() wiederherzustellen.

Ich mag die Stop / Start-Lösung nicht wirklich, weil ich dann Logik brauche, um die Schleife zu unterbrechen, wenn der Verbindungsfehler nicht wiederherstellbar ist. Ich habe beschlossen, den Dienst im Falle eines Fehlers einfach zu stoppen und den Service Manager neu starten zu lassen. (wodurch das Problem im Ereignisprotokoll usw. sichtbar wird)

Mein Handler sieht jetzt so aus:

%Vor%

** EDIT **

Hier ist der Code, den ich beim Start anrufe

%Vor%     
adrianm 12.03.2014 15:02
quelle

Tags und Links