Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Thread verursacht Fehler (https://www.delphipraxis.net/11801-thread-verursacht-fehler.html)

Lefko 13. Nov 2003 23:44


Thread verursacht Fehler
 
Hallo Freunde :hi: ,

ich hab ja schonmal einen Thread zum Thema Thread (lol) aufgemacht, da war dann auch alles sahne,
aber jetz hab ich in ein anderes Programm auch einen Thread (TSoundThread) eingebaut.

Komischerweise meldet er mir einen Fehler, den ich nicht verstehe. Wahrscheinlich liegt das daran, dass ich von Threads immernoch zu wenig ahnung habe!

Hier der Code:

Delphi-Quellcode:
unit USoundThread;

interface

uses
  Classes, MMSystem;

type
  TSoundThread = class(TThread)
  protected
    procedure Execute; override;
  public
       { Public declarations }
    constructor Create(Pfad : string);
  end;

implementation

var SoundPfad : Pchar;          <--------- wenn ich SoundPfad in die Private Declaration setze, kommt eine Access Violation, wenn dem etwas zugeordnet wird

{ TSoundThread }

constructor TSoundThread.Create(Pfad : string);
begin
SoundPfad := pchar(Pfad); //hier kommt die AV mit SoundPfad in der P D
FreeOnTerminate := true;  //wenn SoundPfad ne globale Var ist, dann kommt die AV hier...
inherited Create(false);
end;

procedure TSoundThread.Execute;
begin
  { Place thread code here }
  sndPlaySound(SoundPfad,snd_loop); // kann man ne Wave noch anders inner schleife abspielen?
  //if terminated then break;      // <--- das funktioniert nun nämlich nicht mehr...
end;

end.
und so wird der Thread generiert:

Delphi-Quellcode:
procedure TForm3.FormCreate(Sender: TObject);
var SoundThread : TSoundThread;
begin

...

//Musik starten
if FileExists(ExtractFilePath(Paramstr(0)) + 'Optionen') then
    begin
     F := TInifile.Create(ExtractFilePath(Paramstr(0)) + 'Optionen');
     if not F.ReadBool('Optionen','Background', true) then exit;
    end;

Pfad := ExtractFilePath(Paramstr(0)) + 'Sound\Background.wav';

if FileExists(Pfad) then SoundThread.Create(Pfad);
end;
MfG Lefko.

Bernd Ua 14. Nov 2003 00:05

Re: Thread verursacht Fehler
 
Hi,

lass die Finger von den PChars. Das iss nur die Adresse eines Strings.
Wenn Du darin die Adresse eines Parameters oder lokalen Variablen aufhebst,
hast du nix davon ausser dem ungültigen Zeiger und der beobachteten AV.

Also im Abschnitt private deines Threads eine lokale Variable vom String,
dorthin im Konstruktor den Pfad kopieren und erst beim Abspielen auf PChar typecasten.
Dann ist der String wenigstens da :)

In der Execute Methode würde ich ja die klassiche Schleife vorschlagen

Code:
repeat
...
until Terminated
Grüsse Bernd

NicoDE 14. Nov 2003 00:15

Re: Thread verursacht Fehler
 
Zitat:

Zitat von Bernd Ua
dorthin im Konstruktor den Pfad kopieren und erst beim Abspielen auf PChar typecasten.
Dann ist der String wenigstens da :)

Und um zusätzlich alle Zweifel zu beseitigen, kann UniqueString() für die lokale Variable nicht schaden (siehe Delphi-Hilfe).

Luckie 14. Nov 2003 00:17

Re: Thread verursacht Fehler
 
Das was Herr Ua meint, kannst du auch in meinem Threading Tutorial von meiner Seite nachlesen. Desweiteren empfiehlt es sich, den Thread im angehaltenen Zustan zu erzeugen, was hier gar nicht anders geht, alles nötige zu initialisieren, in diesem Fall, die public Varaible für den Thread und ihn dann mit Resume in den zuteilungsfähigen Zustand zu versetzen.

NicoDE 14. Nov 2003 00:30

Re: Thread verursacht Fehler
 
Zitat:

Zitat von Lefko
kann man ne Wave noch anders inner schleife abspielen?

Zum Beispiel mit SND_ASYNC-Flag im Hintergrund abspielen und irgendwann mit SND_PURGE-Flag wieder stoppen.

Hier ein Beispiel mit einer einkompilierten WAV-Ressource mit der ID 1:
Delphi-Quellcode:
  // Play sound
  PlaySound(MakeIntResource(1), HInstance, SND_RESOURCE or SND_LOOP or
    SND_ASYNC);

  // [...]

  // Stop sound
  PlaySound(MakeIntResource(1), HInstance, SND_RESOURCE or SND_PURGE or
    SND_ASYNC or SND_NOWAIT);

Bernd Ua 14. Nov 2003 09:08

Re: Thread verursacht Fehler
 
Hi NicoDE,

Zitat:

Und um zusätzlich alle Zweifel zu beseitigen, kann UniqueString() für die lokale Variable nicht schaden (siehe Delphi-Hilfe).
Eigentlich ab Delphi 5 einschliesslich unnötig, da ab hier IMHO der Increment und Decrement für RefCounter des Strings
über InterlockedIncrement etc gehandelt wird.

Bernd

choose 14. Nov 2003 09:25

Re: Thread verursacht Fehler
 
Zitat:

Zitat von Bernd Ua
Eigentlich ab Delphi 5 einschliesslich unnötig, da ab hier IMHO der Increment und Decrement für RefCounter des Strings
über InterlockedIncrement etc gehandelt wird.

Hallo Bernd. Oberflächlich betrachtet stimmt das, in den Sourcen steht jeweils etwas in der Form
Code:
LOCK DEC [EAX-skew].StrRec.refCnt
trotzdem glaube ich mich erinnern zu können, dass Kudzu auf einer seiner Sessions zu "Indy10" oder "Threads" auf der diesjährigen EKON (zumindest für D5) ebenfalls vor dem unbedachten Gebrauch gewarnt hat.
Im "Indy In Detph" könne ich hierzu auf Anhieb nichts finden (zumal bei Indy ohnehin Wrapper für alle Basistypen verwendet werden).
Leider habe ich die EKON-CD zZt nicht hier, aber irgendwo bei der TMREW-"Cow-Class" ;) müsste das in seinen Slides stehen...

Bernd Ua 14. Nov 2003 09:45

Re: Thread verursacht Fehler
 
Zitat:

Leider habe ich die EKON-CD zZt nicht hier, aber irgendwo bei der TMREW-"Cow-Class" müsste das in seinen Slides stehen...
Grummel - so so , die Teilnehmer haben die CD schon. Die Speaker noch nicht :(
Bernd

Sharky 14. Nov 2003 09:56

Re: Thread verursacht Fehler
 
Hai,

ich verschiebe den Thread mit meiner Nase mal nach ...... ><((((°> *Sonstiges*
Ist dort wohl besser aufgehoben.

choose 14. Nov 2003 10:00

Re: Thread verursacht Fehler
 
Hallo Bernd,

(kam vor(?)letzte Woche) streng genommen warst Du bei der Session, die ich meine, auch nicht anwesend. Vielleicht grenzt das die Suche weiter ein? Heute Abend werde ich das noch einmal recherchieren.

@Lefko: Um es noch einmal zusammenzufassen. Die solltest den Thread Supended kreieren, und vorerst UniqueString verwenden. Außerdem empfiehlt es sich, den Aufruf des geerben Konstruktors als erste Anweisung in der überschriebenen Implementierung aufzurufen. Abschließend im Konstruktor dann Resume aufrufen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:51 Uhr.
Seite 1 von 2  1 2      

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