Autor Beitrag
mk3
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 36



BeitragVerfasst: Mi 08.10.03 10:33 
Hallo alle zusammen,

ich will die Mailversand in 3 Threads starten und mein Programm warten lassen, bis alle Terminieren. Aber wie mache ich es? Die Code sieht vereinfacht so aus:

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:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
// deklaration von Threads
ThreadArray: array of TVersandThreads;
AnzahlThreads : integer;

// Versand-funktion
function TOutlookOutput.Versende: boolean;
var
  i:integer;
begin
  AnzahlThreads:= 3;
  Setlength(ThreadArray, AnzahlThreads);
  // in einer Schleife die Threads erzeugen
  for i := 0 to length(ThreadArray) - 1 do begin
    ThreadArray[i] := TVersandThreads.Create(true);
    ThreadArray[i].FMsgStore := FMsgStore;
    ThreadArray[i].FreeOnTerminate := True;
    ThreadArray[i].OnTerminate := ThreadDone;
    ThreadArray[i].Resume;
  end

  // Diese Funktion soll True zurückmelden wenn alle Threads Terminieren.
  // Das heisst, dass Versand beendet ist!
  ???
end;  

procedure TOutlookOutput.ThreadDone(Sender: TObject);
var i : integer;
begin
  Dec(AnzahlThreads);
  ???
End;

// jetzt Thread
type
  TVersandThreads = class(TThread)
  private
    procedure DoSomething;
   function SetMessageProps(Message: TRwMapiMessage): boolean;    
  protected
    procedure Execute; override;
  public
    FmsgStore : TrwMapiMsgStore;
end;

implementation

procedure TVersandThreads.Execute;
begin
    DoSomething();
end;

procedure TVersandThreads.DoSomething;
var
  NewMessage: TRwMapiMessage;
  Outbox : TRwMapiFolder;
Begin
   Outbox := FMsgStore.OpenFolder(ftOutbox, alReadWrite);
   NewMessage:= OutBox.CreateMessage;
   SetMessageProps(NewMessage);
   NewMessage.SubmitMessage(asMoveToSentItems, false);
   NewMessage.Free;  
end;



ich habe in der Function ThreadDone eine Variable Erfolgreich auf True gesetzt, wenn AnzahlThreads = 0 und in der function Versende in while-Schleife den Wert von Erfolgreich abgefragt, aber die Anwendung hängt.

Danke sehr für jede Hilfe und jeden Hinweis!
mk

Moderiert von user profile iconKalabutermann: Code- in Delphi-Tags geändert.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 08.10.03 10:53 
MSCH
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1448
Erhaltene Danke: 3

W7 64
XE2, SQL, DevExpress, DevArt, Oracle, SQLServer
BeitragVerfasst: Mi 08.10.03 12:02 
Schau dir mal die Hilfe zu SetEvent an.
grez
msch

_________________
ist das politisch, wenn ich linksdrehenden Joghurt haben möchte?
mk3 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 36



BeitragVerfasst: Mi 08.10.03 15:11 
Danke für die Antworten, aber es hilft mir leider nicht weiter. Ich habe mit der folgenden Code versucht:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
ThreadHandles : array of THANDLE; 

function TOutlookOutput.Execute: boolean;
   ...
    for i:= 0 to length(ThreadArray) - 1 do begin
      // Thread erstellen
      ...
      ThreadHandles[i] := ThreadArray[i].Handle;
      ...
      ThreadArray[i].Resume; 
    end;      

   WaitForMultipleObjects(AnzahlThreads, @ThreadHandles,   
                                     true, 1000);
end;

Wie ich verstanden habe, hilft WaitForMultipleObjects für die Synchronisation.

Ich brauche an der Stelle aber keine Synchronisationsmechanismen. Ich will dass meine Funktion, wo ich Threads erzeuge nur dann einen Wert(true oder false) zurückgibt, wenn alle Threads seine Arbeit zu ende gemacht haben. Also, die Anwendung soll warten, bis alle erzeugte Threads terminieren. Wie mache ich es? Kann mir jemand helfen? :cry:

Danke sehr
mk

Moderiert von user profile iconTino: Code- durch Delphi-Tags ersetzt.
MSCH
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1448
Erhaltene Danke: 3

W7 64
XE2, SQL, DevExpress, DevArt, Oracle, SQLServer
BeitragVerfasst: Mi 08.10.03 15:37 
Wie gesagt, schau dir SetEvent an. Ganz grob; jeder Thread erhöht eine Globale Variable wenn er gestartet wurde und erniedrigt diese, wenn er beendet wurde. Der Letzte Thread gibt ein Event an die Anwendung, dass alles beendet wurde.
Die Variable muss übrigens threadsicher deklariert werden.

Suche in: Delphi-Forum, Delphi-Library WAITFORSINGLEOBJEKT ist hier ganz falsch, wenn ich auf einen Thread warten muss, kann ich den ganzen Code gleich in die Anwendung schreiben, welchen Vorteil hat es sonst Code auszulagern und dann doch zu warten? (Ausnahmen bestätigen die Regel)

grez
msch

_________________
ist das politisch, wenn ich linksdrehenden Joghurt haben möchte?
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mi 08.10.03 21:31 
Und wieso nicht Suche in: Delphi-Forum, Delphi-Library WAITFORMULTIPLEOBJECTS ??
ausblenden Delphi-Quelltext
1:
2:
while WaitForMultipleObjects(<count>, <HandleArray>, True, 100) = WAIT_TIMEOUT do
  Application.ProcessMessages;


Wartet bis alle Threads beendet sind und arbeitet zwischendurch immer wieder die Message-Queue ab, damit der Main-Thread nicht "einfriert"...

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!