AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Via property auf Array zugreifen (Threadsicher?)
Thema durchsuchen
Ansicht
Themen-Optionen

Via property auf Array zugreifen (Threadsicher?)

Ein Thema von TheMiller · begonnen am 25. Feb 2008 · letzter Beitrag vom 25. Feb 2008
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#1

Via property auf Array zugreifen (Threadsicher?)

  Alt 25. Feb 2008, 09:55
Hallo,

nachdem ich große Hilfestellung bekommen habe, habe ich mir den mir genannten Vorschlag zu Herzen genommen, mich eingelesen und an meine Bedürfnisse weiter angepasst. Nun würde ich gerne wissen, ob das was ich gemacht habe, auch wirklich Threadsafe ist und wie ich das testen kann.

Was das Programm macht:

Das Hauptprogramm ruft eine DLL-Form auf, die per Windows.SetParent in die Hauptanwendung eingebunden wird. Danach läd die DLL-Form über eine Thread-Unit Daten, die im Thread bearbeitet werden. Die DLL-Form hat ein Container-Objekt erstellt und bei Treaderstellung an den Thread mit weitergegeben. Die Resultate der Bearbeiteten Daten werden in einem Array in der Container-Klasse gespeichert. Nach Beendigung sendet der Thread eine Message an das Hauptprogramm, welches die Daten aus dem ContainerArray ausliest und das Objekt wieder freigibt, wenn es nix mehr zu tun geben sollte.

Hier mal die entscheidenen Quelltexte:

Container:

Delphi-Quellcode:
type
  TExpData = Array of String;
type
  TContainer=class(TSimpleRWSync)
  private
    FExpData: TExpData;
    
    function getExpData(i: Integer): String;
    procedure setExpData(i: Integer; const Value: String);
    function getExpDataCount: Integer;
  public
    property ExpData[i: Integer]: String read getExpData write setExpData;
    property ExpDataCount: Integer read getExpDataCount;
  end;

function TContainer.getExpData(i: Integer): String;
begin
  BeginRead;
  result:=FExpData[i];
  EndRead;
end;

//Bei folgender Prozedur muss ich die Variable "i" haben, da sonst bei der property die Fehlermeldung "Inkompatible Typen" auftritt.
//Aber ich möchte das Array doch immer nur erhöhen.

procedure TContainer.setExpData(i: Integer; const Value: String);
begin
  BeginWrite;
  SetLength(FExpData, Succ(Length(FExpData)));
  FExpData[High(FExpData)]:=Value; <- Warum muss ich einen Index haben?
  EndWrite;
end;
Thread:

Execute ruft Methode zur Speicherung der Daten in ein Array auf. Das Array ist notwendig. Am Ende wird eine Message an die Hauptanwendung DLL-Form gesendet:

  SendMessage(FHndl, WM_CALLBACK, cb_id, LongInt(PChar(s))); Somit weis die Form, dass alle Daten da sind und sie damit arbeiten kann.

Alle Methoden etc. arbeiten miteinander, funktionieren und die richten Daten kommen richtig dort an, wo sie ankommen sollen, doch meine Frage ist nun - da das noch relativ neu für mich war - ob das Threadsafe ist und wie ich das testen kann.

Wäre nett, wenn ihr mal drüberschauen könntent. (Achso, und ich habe im Quelltext noch eine Frage zur Indexvariablen. Vielleicht könnt ihr mir da noch einen Tipp geben.

Danke im Voraus!
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Via property auf Array zugreifen (Threadsicher?)

  Alt 25. Feb 2008, 10:51
Zum Index:
Anscheinend brauchst du den nicht, da du beim Schreiben immer nur hinten anhängen willst. Dann lass doch den Index im Property und in der set-Methode weg.
Den Index bräcuhtest du, wenn du irgendein Element des Arrays ändern willst. Aber du willst ja nur anhängen.
btw.: Warum benutzt du keine Stringliste. Wäre OOP-konformer, die Array-Lösung wie du sie derzeit umgesetzt hat, wird mit zunehmender Zahl an Elementen langsamer.

Zum Container:
Das hatten wir ja im anderen Thread soweit. Du hast aber getExpDataCount Threadsafe mit begin- und endread ausgeführt?
Und wie gesagt: Du hast TContainer jetzt von TSimpleRWSync abgeleitet. Du kannst ohne Probleme auch von TMultiReadExclusiveWriteSynchronizer (kurz: TMREWSync) ableiten. Dahinter steckt eine andere Art des Synchronisierens (je nach Anwendung ist das eine oder das andere schneller). Die öffentlichen Methoden sind netterweise dieselben. Dadurch muss man sonst nix ändern.


zum Callback:
Hier hast du jetzt eine zweite Variante des Synchronisierens hineingebracht. wenn du bei der schönen ContainerMethode bleiben willst, dann schreibe doch s auch in den Container und starte dort das Callback:
Delphi-Quellcode:
type
  TContainer=class(TSimpleRWSync) //oder eben: TContainer=class(TMREWSync)
  private
    FExpData: TExpData; //Besser: TStringList
    Fs:string; //blöder kurzer Name ;-)
    
    function getExpData(i: Integer): String;
    procedure setExpData(i:Integer; const Value: String);
    function getExpDataCount: Integer;

    procedure sets(s:string);
    function gets:string;
    //und hier die Methoden für den Callback wie in dem Beispiel im letzten Thread

  public
    procedure appendExpData(Value:string);
    property ExpData[i: Integer]: String read getExpData write setExpData;
    property ExpDataCount: Integer read getExpDataCount;
    property s:string read....
  end;
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: Unterhaching
11.412 Beiträge
 
Delphi 12 Athens
 
#3

Re: Via property auf Array zugreifen (Threadsicher?)

  Alt 25. Feb 2008, 10:58
Ganz wichtig: vergiß die try...finally...end Blöcke nicht, sonst dürfte es ganz schnell Dead-Locks geben, wenn es mal zu einer Exception kommt und ich glaube nicht, dass Du das willst

......
Daniel Lizbeth
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#4

Re: Via property auf Array zugreifen (Threadsicher?)

  Alt 25. Feb 2008, 11:19
die Try-Except Blöcke werde ich noch einfügen. Was muss beim Except rein? Was spezielles, oder einfach nur eine Fehlerbehandlung bzw. gar nix?

Ein Array habe ich genommen, weil ich es schöner und eigentlich Professioneller finde. Aber wenn es langsamer wird. Ich erwarte viele Werte. Muss ich also nochmal überdenken.

Den Index MUSSTE ich definieren, da sonst immer die Meldung "Inkompatible Typen" in der Setter-Methode aufkamen. Ohne diese Variable kann nicht komipiliert werden. Warum weis ich auch nicht.

Die Message habe ich gesendet, da ich eine Variable mit übergeben muss um die Anwendung erkennen zu lassen, welche Operation sie mit den Daten ausführt. Also eine Case-Of. Oder soll ich da besser noch eine Variable bspw. DataType definieren und dann darüber die Case-Of laufen lassen?
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: Unterhaching
11.412 Beiträge
 
Delphi 12 Athens
 
#5

Re: Via property auf Array zugreifen (Threadsicher?)

  Alt 25. Feb 2008, 11:21
Zitat von DJ-SPM:
die Try-Except Blöcke werde ich noch einfügen. Was muss beim Except rein?
Hat keiner was von EXCEPT gesagt
Delphi-Quellcode:
procedure TContainer.setExpData(i: Integer; const Value: String);
begin
  BeginWrite;
  try
    SetLength(FExpData, Succ(Length(FExpData)));
    FExpData[High(FExpData)]:=Value; <- Warum muss ich einen Index haben?
  finally
    EndWrite;
  end;
end;
So als Beispiel

......
Daniel Lizbeth
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: Unterhaching
11.412 Beiträge
 
Delphi 12 Athens
 
#6

Re: Via property auf Array zugreifen (Threadsicher?)

  Alt 25. Feb 2008, 11:24
Zitat von DJ-SPM:
Den Index MUSSTE ich definieren, da sonst immer die Meldung "Inkompatible Typen" in der Setter-Methode aufkamen. Ohne diese Variable kann nicht komipiliert werden. Warum weis ich auch nicht.
Warum? Einfach, Du deklarierst eine Array-Eigenschaft mit Index und die Getter- und Setter-Methoden müssen zu dieser Deklaration kompatibel sein. Ich würde es wie folgend ändern:
Delphi-Quellcode:
type
  TContainer=class(TSimpleRWSync)
  private
    function getExpData(i: Integer): String;
  public
    procedure AddExpData(const Value: String);

    property ExpData[i: Integer]: String read getExpData;
  end;
Der Rest ist nicht aufgeführt

.......
Daniel Lizbeth
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#7

Re: Via property auf Array zugreifen (Threadsicher?)

  Alt 25. Feb 2008, 11:29
Dankesehr.

Mit dem "Except" habe ich einfach zu schnell gelesen. Das leuchtet auch eher ein - die Zugriffe müssen ja auf jeden Fall wieder freigegeben werden. War dumm von mir!

Nunja, das mit dem Array hat sich demnach auch erledigt. Ich werde wohl doch eine StringList benutzen (obwohl ich arrays schöner finde). Ist doch bei sehr vielen Daten besser, oder?

Danke!
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#8

Re: Via property auf Array zugreifen (Threadsicher?)

  Alt 25. Feb 2008, 11:39
Zitat:
Den Index MUSSTE ich definieren, da sonst immer die Meldung "Inkompatible Typen" in der Setter-Methode aufkamen. Ohne diese Variable kann nicht komipiliert werden. Warum weis ich auch nicht.
Nicht umbedingt, denn du könntest auch einfach hinter der Metode Overload; schreiben.

Das sind ja zwei unterschiedliche Aufruf Parameter. Dann geht das.
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: Via property auf Array zugreifen (Threadsicher?)

  Alt 25. Feb 2008, 13:22
Zitat von DJ-SPM:
Den Index MUSSTE ich definieren, da sonst immer die Meldung "Inkompatible Typen" in der Setter-Methode aufkamen. Ohne diese Variable kann nicht komipiliert werden. Warum weis ich auch nicht.
Ach ja, du willst ja immer hinten anhängen und einen bestimmten Array-Wert lesen. Das geht innerhalb eines Propertys nicht (da habe ich ja auch einen Fehler oben - Berichtigung folgt sogleich). Die Lösung haben meine Vorredner ja schon gezeigt.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#10

Re: Via property auf Array zugreifen (Threadsicher?)

  Alt 25. Feb 2008, 13:59
Hm stimmt.

Jetzt würde ich das Array doch gerne lassen... Wie viel langsamer ist denn ein Array gegenüber einer Stringliste und ab wie vielen Einträgen macht sich das denn bemerkbar?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:25 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz