Jump to content

Recommended Posts

Posted

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;

 

 

Posted

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.

 

Posted

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

 

Posted

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? :)

Posted

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

 

Posted

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.

Join the conversation

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

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...