Ich habe eine Anwendung, die mit einer vom Hersteller bereitgestellten API arbeiten muss, um Screen Pops auszuführen, wenn ein Anruf an die Nebenstelle des Benutzers weitergeleitet wird. Ein anderer Entwickler arbeitete daran, die API zum Laufen zu bringen und lieferte eine Prototyp-Wrapper-Klasse, die nicht ganz richtig ist, und ich versuche, es richtig zu machen.Wie man mit dem Starten/Stoppen der API-Schnittstelle umgeht, die lange dauern kann
Da diese API für einige Minuten vor der Rückkehr blockieren kann, begannen die Entwickler den API-Schnittstelle Code in einem separaten Thread, wie folgt aus:
// constructor
public ScreenPop(...params...)
{
...
t = new Thread(StartInBackground);
t.Start();
)
private void StartInBackground()
{
_listener = new ScreenPopTelephoneListener();
_bAllocated = true;
_listener.Initialize(_address);
_bInitialized = true;
_listener.StartListening(_extension);
_bListening = true;
}
Der Aufruf zum Initialisieren ist derjenige, hängen könnte, wenn die Der Telefonserver reagierte nicht.
Ich glaube nicht, dass es von Seiten des Entwicklers absichtlich gemacht wurde, aber wenn die API auf diese Weise initialisiert wird, läuft der Thread weiter, so dass ich jetzt den Thread stoppen muss, bevor ich aufräumen kann Wenn ich will. Ich muss auch Invoke verwenden, um Ereignisse aus dem Thread zu bekommen, wie andere in meiner vorherigen Frage so freundlich darauf hingewiesen haben, aber das funktioniert jetzt.
Wie auch immer, hier ist die Logik verwendet, um alles zu beenden und aufzuräumen:
public void ShutdownFunc()
{
try
{
if (_bListening)
{
_listener.StopListening();
_bListening = false;
}
if (_bInitialized)
{
_listener.Shutdown();
_bInitialized = false;
}
if (_bAllocated)
{
_listener = null;
_bAllocated = false;
}
}
}
Natürlich gibt es ein try/catch um den ganze Schlamassel Ausnahmen zu verhindern, nicht behandelte.
Mein größtes Problem ist, wie kann ich den Shutdown-Code aufrufen, wenn der API-Schnittstellencode in einem separaten Thread ausgeführt wird? Ich muss aufräumen, wenn sich der Benutzer abmeldet und sich dann wieder anmeldet, da die API sonst verwirrt wird. Thread.Abort funktioniert nicht, da es sich nicht an einem Ort befindet, an dem die Ausnahme abgefangen werden kann, und die "volatile bool" -Methode funktioniert auch nicht, aus offensichtlichen Gründen (meistens ist der API-Thread nicht aktiv).
Es scheint also keine Möglichkeit zu geben, die Abschaltlogik aufzurufen, wenn der API-Schnittstellencode in einem separaten Thread ausgeführt wird. Thread.Abort() umgeht die gesamte Logik und beendet den Thread ohne zu bereinigen. Der Aufruf der Shutdown-Logik vom GUI-Thread hängt beim Aufruf der Shutdown-Methode. Was kann ich also tun?
Die IDispose-Schnittstelle fügt nur eine weitere Abstraktionsebene in den GUI-Thread ein und löst das Problem hier nicht.
Für jetzt, um den Rest des Codes entwickelt zu bekommen, beseitige ich Threads vollständig. Bevor ich die App freigebe, muss ich das herausfinden.
Jeder?
Danke,
Dave
Das würde funktionieren, wenn die Initialize die einzige Sache in dem neuen Thread war. Der Thread läuft weiter, und ich muss wissen, wie ich ihn stoppen kann ... – DaveN59
Was ich vorgeschlagen habe, bestand darin, Initialize und StartListening zu teilen, damit nach der Initialisierung nur der Hintergrund-Thread zuhören kann. Die Struktur ist Haupt -> Arbeiter -> Initialisierer. Der Initialisierer wird beendet und der Mitarbeiter muss die Daten abhören und verarbeiten. – em70
Ich bekomme das, und es ist eine gute Idee, aber ich habe immer noch das Problem, wie man den Arbeitsthread herunterfährt. Ich bekomme das noch nicht, und es gibt keine Möglichkeit, eine halbe Antwort zu geben ... – DaveN59