StefanP Posted October 21, 2013 at 03:38 PM Posted October 21, 2013 at 03:38 PM 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; Quote
photron Posted October 21, 2013 at 03:54 PM Posted October 21, 2013 at 03:54 PM 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. Quote
StefanP Posted October 21, 2013 at 04:38 PM Author Posted October 21, 2013 at 04:38 PM 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 Quote
borg Posted October 21, 2013 at 07:14 PM Posted October 21, 2013 at 07:14 PM Die Delphi Bindings sind thread-safe, VCL ist aber nicht thread-safe. Da können wir allerdings nichts gegen machen. Wir müssen den Callback ja aus einem anderen Thread heraus aufrufen, wie soll das sonst gehen? Quote
StefanP Posted October 22, 2013 at 10:06 AM Author Posted October 22, 2013 at 10:06 AM 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 Quote
AuronX Posted October 22, 2013 at 11:59 AM Posted October 22, 2013 at 11:59 AM 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. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.