Jump to content

[Delphi] Sind Device Events threadsafe?


Recommended Posts

Moin!

 

Siehe Topic. Ich habe das Gefühl, dass einige Events nicht threadsafe sind. Die Applikation hängt, sobald ich innerhalb eines Events (Callback) wie

- TBrickletPtc.OnTemperature

- TBrickletTemperature.OnTemperature

- TBrickletAmbientLight.OnIlluminance

- TBrickletDistanceIr.OnDistance

eine Textzeile zu einem TMemo zufügen will, um den Event zu protokollieren.

Wenn ich das Programm dann im Debugger stoppe, dann bekomme ich als Callstack

 

> :7c91e460 ntdll.KiUserCallbackDispatcher

  :76af4e31 ; C:\WINDOWS\system32\winmm.dll

  :7c80b729 ; C:\WINDOWS\system32\kernel32.dll

 

 

Hier mal ein Beispiel:

 

procedure TfrmMain.TfOnDistanceIrChanged(Sender: TBrickletDistanceIr;

                                        const Distance: Word);

begin

  // The following (TLabel) seems to work always or almost always

  lblDistanceIrCurrent.Caption := 'Distance: ' + IntToStr(Distance) + ' mm';

 

  // The following (TMemo) makes the app unresponsive and hang

  aMemo.Lines.Add('Distance: ' + IntToStr(Distance) + ' mm');

end;

 

 

Link zu diesem Kommentar
Share on other sites

Die Callbacks werden von einem Thread der IPConnection aufgerufen. Du darfst aber mit dem GUI nur direkt aus dem Haupt-Thread deines Programms heraus interagieren, sprich was du da tust ist nicht erlaubt.

 

Dass das Programm zufällig in der KiUserCallbackDispatcher Funktion von Windows steht würde ich ehr als zufällig betrachten. Diese Funktion ist eine Funktion des Windows Kernels, sie hat nichts direkt mit den Delphi Bindings zu tun.

 

Um das Problem zu lösen musst du die Interaktion mit dem GUI in den Haupt-Thread verschieben, dazu kannst du z.B. TThread.Synchronize verwenden.

 

Link zu diesem Kommentar
Share on other sites

Das mit der Threadsynchronisierung bzgl. VCL ist bekannt - ich mach das schon ein paar Jahre...

Daher die Frage. Dann ist die Sache klar, werde eine thread-sichere Queue einbauen.

Steht dazu irgendwo etwas in der Doku? Habe nix gefunden - lediglich einen Eintrag hier Forum, der aussagt, dass C/C++ Bindings threadsafe sind.

 

Gruß

  Stefan

 

Link zu diesem Kommentar
Share on other sites

Das Gute vorweg:

Nachdem nun alle Events nur noch ein PostMessage() zum Mainthread machen, läuft es bislang stabil.

 

Zum Thema Threadsafety:

Ich kenne es von vielen kommerziellen Bibliotheken, das Komponenten (Klassen) ihre Events in dem Threadkontext generieren, in dem die Klasse per Create() instantiert wurde. Sie übernehmen also intern die Synchronisierung, falls im Hintergrund Workerthreads verwendet werden.

Will sagen: Wenn ich meine Bricklets im Mainthread instantiere, dann werden auch ihre Events im Mainthread generiert.

 

Stefan

 

Link zu diesem Kommentar
Share on other sites

Dann müsstest du im Main-Thread aber aktiv die Kontrolle an die Bibliothek übergeben, damit das möglich ist... ungefähr so wie es in den PHP-Bindings wegen mangelnden multi-threadings gemacht wird.

 

Was nicht geht ist "heimlich" - also ohne Wissen des Programmierers - Dinge im Main-Thread zu tun, da der Kontrollfluss ja ab einem bestimmten Punkt wieder in deiner Hand liegt und aktiv durch dich abgegeben werden muss.

 

Nomenklatur wäre aber dennoch eine andere ^^ Threadsafe sind die Bindings nämlich dann, wenn ich sicher aus mehreren Threads auf sie zugreifen kann ohne dass es knallt.

Link zu diesem Kommentar
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...