AgeArtmann - Mi 07.11.07 00:33
Titel: Deadlock bei Tab öffnen und schließen im Thread
Hallo,
Hab hier eine Deadlocksituation an der ich mir die Zähne ausbeiße
bin schon lange am tüfteln, komme aber einfach nicht drauf.
Hat jemand von euch eine Idee?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| procedure TDownload.Execute; var TempTabSheet:TTabSheet; begin CoInitialize(nil); try age_cs.Enter; TempTabSheet:= CreateTabBrowser('about:blank', 'TAB'); finally age_cs.Leave; end;
try age_cs.Enter; TempTabSheet.Free; finally age_cs.Leave; end;
CoUnInitialize; end; |
age_cs ist auch initialisiert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| initialization OleInitialize(nil); CoInitialize(nil); age_cs := TCriticalSection.Create; finalization OleUninitialize; CoUninitialize; age_cs.Free; end. |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52:
| function CreateTabBrowser(sURL, sCaption: string): TTabSheet; var ts: TTabSheet; WB: TWebbrowser; begin ts := TTabSheet.Create(PageControl); Result := ts; try ts.PageControl := PageControl; ts.Parent := PageControl; ts.Caption := sCaption; WB := TWebbrowser.Create(ts);
TControl(WB).Parent := ts; WB.Align := alClient; WB.Silent := True; WB.Visible := True;
PageControl.ActivePage := ts;
WB.OnNewWindow2 := Form1.WebBrowser_Tab_NewWindow2; if Trim(sURL) <> '' then begin WB.Navigate(sURL); WB_Warten_spec(WB,0); end; except ts.Free; Log('Fehler beim Tab createn',3); end; end; |
Wenn ich nun Versuche 10 Threads zu starten hängt er sich nach dem 2. Tab auf
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure TForm1.Button15Click(Sender: TObject); var j:Integer; DownloadThreads: array [0..9] of TDownload; begin for j := 0 to 9 do begin DownloadThreads[j] := TDownload.Create(True); DownloadThreads[j].FreeOnTerminate := True; DownloadThreads[j].Index := j; DownloadThreads[j].Resume; end; end; |
Ich hab irgendwie das Gefühl er ignoriert die CriticalSection und überschneidet das Erstellen und schließen der Tabs
Vielen Dank im Voraus
MfG AgeArtmann
alzaimar - Mi 07.11.07 09:01
VCL-Komponenten sollen nicht in einem Thread angesprochen werden. Das funktioniert einfach nicht. Die visuellen Komponenten dürfen nur im Kontext des Hauptthreads manipuliert werden.
Hierzu eignet sich die Synchronize-Methode der TThread-Klasse.
Anstatt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| Procedure TMyThread.Execute; Begin ... MainForm.Control.Caption := 'Foobar'; ... End; |
Musst Du sowas machen;
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| Procedure TMyThread.DoUpdateControl; Begin MainForm.Control.Caption := 'Foobar'; End;
Procedure TMyThread.Execute; Begin ... Synchronize (DoUpdateControl); ... End; |
Das ist ein bisserl umständlich und auch häßlich, lässt sich aber nicht vermeiden.