Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 11:26

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Mo Dez 19, 2005 18:46 
Offline
DGL Member

Registriert: So Okt 23, 2005 08:45
Beiträge: 9
Wohnort: Dresden
Ich Bastel in meinem aktuellem Project das erste mal mit Threads rum, und Wenn ich darin Showmessage(...) oder Ein Selbst gebautes Message-Form verwende (einfach nur zeigen oder erstellen und zeigen und danach wieder zerstören... selber Effect) wenn ich dann das Programm schliesse bekomm ich eine Exception durch die TWinControl.DestroyWindowHandle... Kann mir jemand sagen woran das liegt und wie ich das verhinder?
Ich bin mir auch sehr sicher das alle Threads beim schliessen schon beendet sind (alle Threads tragen sich in eine TList ein und kurz vorm Terminieren wieder aus und beim schliessen des Hauptforms frag ich den Count der TList ab)

Ich hoffe Ihr könnt mir helfen, schonmal Danke an alle die es versuchen :wink:

_________________
MfG SonicFX


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Dez 19, 2005 19:27 
Offline
DGL Member

Registriert: Fr Dez 19, 2003 14:27
Beiträge: 107
Wohnort: Indianapolis, USA
Ich glaube du solltest erst mal ein wenig ueber Threads nachlesen:
http://www.pergolesi.demon.co.uk/prog/threads/ToC.html

Du darfst nicht von verschiedenen Threads aus auf gleiche Resourcen zugreifen ohne dass das synchronisiert wird.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Dez 19, 2005 20:02 
Offline
DGL Member

Registriert: So Okt 23, 2005 08:45
Beiträge: 9
Wohnort: Dresden
Wenn ich aber wenn ich ein Form create is das doch nicht die selbe Resource...
Code:
  1. procedure TMyThread.Meldung(Text: String);
  2. var MF: TMeldungForm;
  3. begin
  4.      MF := TMeldungForm.Create(nil);
  5.      try
  6.         MF.Label1.Caption := Text;
  7.         MF.ShowModal;
  8.      finally
  9.         MF.free;
  10.         MF := nil;
  11.      end;
  12. end;

und ich denk nicht das das bei Showmessage anders ist...

[EDIT] Das mit den Threads funtzt alles einwandfrei (auch gemeinsam genutzte Variablen) ausser ich versuche aus dem Threads heraus eine Nachricht anzuzeigen...

_________________
MfG SonicFX


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Dez 19, 2005 20:12 
Offline
DGL Member

Registriert: So Okt 23, 2005 08:45
Beiträge: 9
Wohnort: Dresden
Ich hab Obrigen code nochmal ausprobiert und festgestellt das eine andere Exception in dem fall aufgerufen wird.
TCanvas.RequiredState ruft eine EInvalidOperation.CreateRes auf... ich denk mal dies liegt am nil als Create Argument.

_________________
MfG SonicFX


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 20, 2005 02:04 
Offline
DGL Member

Registriert: Fr Dez 19, 2003 14:27
Beiträge: 107
Wohnort: Indianapolis, USA
SonicFX hat geschrieben:
Wenn ich aber wenn ich ein Form create is das doch nicht die selbe Resource...

Und wo denkst du werden die Messages fuer diese Form behandelt?

SonicFX hat geschrieben:
[EDIT] Das mit den Threads funtzt alles einwandfrei (auch gemeinsam genutzte Variablen) ausser ich versuche aus dem Threads heraus eine Nachricht anzuzeigen...

Das ist mit Threads immer so, alles funtzt einwandfrei bis zum crash :D


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 20, 2005 12:06 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Tokter etwas ähnliches gibt es bei uns im Wiki auch in Deutsch. Mag vielleicht nicht ganz so umfangreich sein aber ich denke doch mal ausreichend.

SonicFX: Wie Tokter schon sagte. Wenn du auch verschiedene Variablen oder Klassen zugreifst, dann solltest du dir genau überlegen was alles synchronisiert werden muss. Und vor allem wann etwas Synchronisiert werden muss. OnTerminate einer Threadklasse wird von Hause aus schon synchronisiert.

Fenster und Threads gehen grundsätzlich. Wenn du ein Fenster in einem neuen Thread erstellst werden die Nachrichten dann in diesem Thread abgearbeitet. Allerdings sobald du komplexere Fenster hast in denen auch noch mit Bitmaps (GDI) gearbeitet wird, dann gibt es nach einer Zeit Fehler. Aber prinzipiell sollte sowohl ein ShowMessage als auch ein TForm.Create funktionieren. Dabei spielt es auch keine Rolle ob du bei Create ein Nil übergeben hast oder nicht. Habe so etwas selber schon häufig genug gemacht. Allerdings wäre ich immer sehr vorsichtig damit. Und nach möglichkeit würde ich die Fenster aus Threads raus lassen.

Je nachdem was du vor hast würde es sich aber sowieso auch anbieten ein Event zu machen welches Synchronisiert aufgerufen wird und welches dann die Meldung anzeigt. Aber da stellt sich mir wie üblich die Frage was genau du damit vor hast?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 20, 2005 13:28 
Offline
DGL Member

Registriert: So Okt 23, 2005 08:45
Beiträge: 9
Wohnort: Dresden
Ich umgeh das Problem jetzt einfach indem ich Die Meldungen in eine Liste, eines Forms welches immer da ist, schreiben lass.
Da das eh nur für den User is damit ers Sieht und nicht damit arbeite sollte das weniger Problematisch sein.

_________________
MfG SonicFX


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 20, 2005 14:59 
Offline
DGL Member

Registriert: Fr Dez 19, 2003 14:27
Beiträge: 107
Wohnort: Indianapolis, USA
Lossy eX hat geschrieben:
Fenster und Threads gehen grundsätzlich. Wenn du ein Fenster in einem neuen Thread erstellst werden die Nachrichten dann in diesem Thread abgearbeitet.


Diese Aussage stimmt nur wenn du das Fenster von Hand mittels Win32 API calls selbst erzeugt hast und dann auch deine eigene Message Loop in dem Thread durchlaeufst. Wenn du von TForm sprichst ist das falsch, erstens ist die VCL nicht thread safe und zweitens behandelt ein Thread von sich aus ueberhaubt keine Nachrichten. Wenn das bei dir nicht abgestuerzt ist dann ist das pures Glueck. Wenn du das sauber machen willst dann erstellst du alles VCL verwannte im Haupt Thread und alle anderen Thread greifen synchonisiert darauf zu wenn sie was angezeigt haben moechten.

Wenn du unbedingt Fenster in einem Thread erzeugen willst dann must du das so machen:
Hab den Beispiel code hier gefunden: http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21595998.html

Code:
  1.  
  2. type
  3.   TShowWndThread = class(TThread)
  4.   private
  5.     FMsg1: String;
  6.   protected
  7.     procedure Execute; override;
  8.   public
  9.     constructor Create(const Msg: String);
  10.     destructor Destroy; override;
  11.   end;
  12.  
  13.  
  14. // / / / / / / / / / / / / /  / / /
  15.  
  16.  
  17. implementation
  18.  
  19. {$R *.DFM}
  20.  
  21.  
  22. const
  23. ID_OKBut = 100;
  24.  
  25. var
  26. aSelf: TShowWndThread;
  27. hThreadWnd: THandle = 0;
  28.  
  29. function WndProc(hWnd,Msg,wParam,lParam:Integer):Integer; stdcall;
  30. begin
  31. case Msg of
  32.   WM_DESTROY: PostQuitMessage(0);
  33.   WM_COMMAND: if LOWORD(wParam) = ID_OKBUT then PostMessage(hWnd,WM_CLOSE,0,0);
  34.   end;
  35. Result := DefWindowProc(hWnd,Msg,wParam,lParam);
  36. end;
  37.  
  38. constructor TShowWndThread.Create(const Msg: String);
  39. begin
  40. FreeOnTerminate := True;
  41. inherited Create(False);
  42. if aSelf <> nil then
  43.   Raise Exception.Create('Create Failed - There can only be one instance of TAskThread');
  44. aSelf := Self;
  45. FMsg1 := Msg;
  46. end;
  47.  
  48. destructor TShowWndThread.Destroy;
  49. begin
  50. aSelf := nil;
  51. inherited Destroy;
  52. end;
  53.  
  54.  
  55. procedure TShowWndThread.Execute;
  56. var
  57. wClass:   TWndClass;
  58. mainMsg: TMSG;
  59. begin
  60. ZeroMemory(@wClass, SizeOf(wClass));
  61.  
  62. with wClass do
  63.   begin
  64.   hInstance := sysInit.hInstance;
  65.   hIcon := LoadIcon(0,IDI_QUESTION);
  66.   lpfnWndProc := @WndProc;
  67.   hbrBackground := COLOR_BTNFACE+1;
  68.   lpszClassName := 'TMW Class';
  69.   hCursor := LoadCursor(0,IDC_ARROW);
  70.   end;
  71.  
  72. Windows.RegisterClass(wClass);
  73.  
  74. hThreadWnd := CreateWindowEX(0,wClass.lpszClassName,'No See',
  75.           WS_SYSMENU or WS_DLGFRAME or WS_CAPTION or WS_VISIBLE,
  76.           140,140,180,110,0,0,hInstance,nil);
  77.  
  78. CreateWindow('BUTTON', 'O K',
  79.     WS_VISIBLE or WS_CHILD or BS_PUSHBUTTON or WS_TABSTOP,
  80.     57,50,66,24,hThreadWnd,ID_OKBut,hInstance,nil);
  81.  
  82. SendMessage(CreateWindow('STATIC', PChar(FMsg1), WS_VISIBLE or WS_CHILD or SS_CENTER,
  83.     1,1,173,46,hThreadWnd,46,hInstance,nil),
  84.     WM_SETFONT,GetStockObject(ANSI_VAR_FONT),0);
  85.  
  86.  
  87. // IMPORTANT
  88. // below is the GetMessage loop for this thread, which does ONLY window message for this thread
  89. // without it the CreateWindow( ) functions abouve are useless
  90. // the ShowMessage( ) procedure does NOT place this in any thread
  91. if hThreadWnd <> 0 then
  92.   while GetMessage(mainMsg,0,0,0) do
  93.     if not IsDialogMessage(hThreadWnd, mainMsg) then
  94.       begin
  95.       TranslateMessage(mainMsg);
  96.       DispatchMessage(mainMsg);
  97.       end;
  98. end;
  99.  
  100. // / / / / / / / / / / / / / / / /
  101.  
  102.  
  103. procedure TForm2.but_ThreadSendMsgClick(Sender: TObject);
  104. begin // button click
  105. TShowMsgThread.Create(Handle);
  106. end;
  107.  
  108. initialization
  109.  
  110. finalization
  111. PostMessage(hThreadWnd, WM_DESTROY, 0,0);
  112.  
  113. end.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 20, 2005 15:35 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Ich weiß, dass die VCL nicht Threadsafe ist. Deswegen sagte ich ja auch einfache Fenster. Das war ein Erfahrungbericht und keine technische Sache. So lange die Fenster (TForm) einfach gehalten sind kannst du es durchaus in einem Thread erstellen. Auch wenn man es nach möglichkeit vermeiden sollte. Sich deswegen auf die WindowsAPI zu stürzen halte ich persönlich auch nicht unbedingt für sinnvoll. Das ist aber reine Gschmackssache und bisher habe ich es auch ohne hinbekommen. Das meist in dem man alleine schon die Struktur der Anwendung verändert hat.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 14 Queries | GZIP : On ]