Autor Beitrag
AgeArtmann
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mi 07.11.07 00:33 
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?

ausblenden 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;
    //kritischer Prozess Begin
    TempTabSheet:= CreateTabBrowser('about:blank''TAB');
  finally
    age_cs.Leave;
  end;

  try
    age_cs.Enter;
    //kritischer Prozess Begin
    TempTabSheet.Free;
  finally
    age_cs.Leave;
  end;

  CoUnInitialize;
end;


age_cs ist auch initialisiert:

ausblenden 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.


ausblenden volle Höhe 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
  // Create a new TabSheet
  ts := TTabSheet.Create(PageControl);
  Result := ts;
  try
    // Assign TTabSheet Properties
    ts.PageControl := PageControl;
    ts.Parent := PageControl;
    ts.Caption := sCaption;
    //ts.PageIndex := PageControl.ActivePageIndex + 1;

    // Create a TWebbrowser instance
    WB := TWebbrowser.Create(ts);

    // put TWebbrowser on TTabSheet
    TControl(WB).Parent := ts;
    // or:   Ts.InsertControl(WB);

    // Assign Webbrowser Properties
    WB.Align := alClient;
    WB.Silent := True;
    WB.Visible := True;

    PageControl.ActivePage := ts;

    // Assign Webbrowser Events
    //WB.OnProgressChange := WebBrowser1ProgressChange;
    //WB.OnStatusTextChange := WebBrowser1StatusTextChange;
    //WB.OnTitleChange := WebBrowser1TitleChange;
    WB.OnNewWindow2 := Form1.WebBrowser_Tab_NewWindow2;
    //WB.OnCommandStateChange := WebBrowser1CommandStateChange;
    //WB.OnDownloadComplete := WebBrowser1DownloadComplete;
    //WB.OnDocumentComplete := WebBrowser1DocumentComplete;
    //WB.OnDownloadBegin := WebBrowser1DownloadBegin;
    //WB.FNavForward := False;
    //WB.FNavBack := False;

    // Navigate to a URL
    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

ausblenden 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..9of TDownload;
begin
// die ersten 10 threads starten
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Procedure TMyThread.Execute;
Begin
  ...
  MainForm.Control.Caption := 'Foobar'// <<--- Zugriff auf VCL, hier wird der Thread hängen bleiben
  ...
End;

Musst Du sowas machen;
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Procedure TMyThread.DoUpdateControl;
Begin
  MainForm.Control.Caption := 'Foobar'// <<--- Zugriff auf VCL
End;

Procedure TMyThread.Execute;
Begin
  ...
  Synchronize (DoUpdateControl);        // <<--- So klappts
  ...
End;

Das ist ein bisserl umständlich und auch häßlich, lässt sich aber nicht vermeiden.

_________________
Na denn, dann. Bis dann, denn.