2017-03-09 4 views
-1

Ich habe eine Konsolenanwendung, die, wenn sie ausgeführt wird, E-Mails über googles SMTP-Client sendet.Wie kann ich wissen, ob aktive Threads vorhanden sind?

-Code dafür:

private void SendEmailThread(MailMessage message) 
{ 
    Thread thread = new Thread(() => _mailService.SendEmail(message)); 
    thread.Start(); 
    thread.Join(); 
} 

Wie kann ich wissen, wenn alle Threads abgeschlossen sind?

Gibt es eine globale Eigenschaft, die auf ThreadsRunning = 0 gesetzt wird, wenn alle fertig sind?

Ich möchte eine Nachricht an die Konsole senden, wenn alle E-Mails gesendet wurden, und das ist getan, wenn ich keine Threads mehr habe.

Etwas wie:

if(allThreadsDone){ 
    Console.WriteLine("All mails are sent"); 
} 
+0

Siehe diese Fragen: [Aussetzen und Benachrichtigen von Threads, wenn Arbeit zu tun ist] (http://stackoverflow.com/questions/210020/suspending-and-notifying-threads-when-there-is-work-to- do) und [C# entspricht Java's warte und benachrichtige?] (http://stackoverflow.com/questions/209281/c-sharp-equivalent-to-javes-wait-and-notify). Schauen Sie auch auf ['Task.Run'] (https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.run.aspx), wenn Sie keinen dedizierten E-Mail-Absender-Thread möchten . – Romoku

+1

Aus dem Aussehen ist Ihr Code im Wesentlichen die gleiche wie '_mailService.SendEmail (Nachricht);' weil Sie 'Join' verwenden, die auf den Thread wartet, um abzuschließen. – TheLethalCoder

+0

Von MSDN: Blockiert den aufrufenden Thread, bis der Thread, der von dieser Instanz dargestellt wird, beendet wird, während das standardmäßige COM- und SendMessage-Pumpen fortgesetzt wird. – TheLethalCoder

Antwort

3

Ihr Code ist eigentlich (mehr oder weniger) synchron laufen. Dies liegt daran, dass Thread.Join den aufrufenden Thread blockiert, bis der andere Thread endet. Oder wie MSDN sagt:

Blockiert den aufrufenden Thread, bis die von dieser Instanz dargestellten Thread beendet wird, während sie weiterhin Standard-COM und Sendmessage Pumpen durchzuführen.

So im Wesentlichen alles, was Sie tun müssen, ist nach dem letzten Aufruf SendEmailThread nur Ihre Nachricht drucken:

Console.WriteLine("All mails are sent"); 

Für das, was Sie versuchen, schlage ich vor, Sie in Task.WhenAll aussehen zu erreichen. In Ihrem Fall so etwas wie:

var tasks = new List<Task>(); 
foreach (var message in messages) 
{ 
    tasks.Add(Task.Run(() => _mailService.SendEmail(message))); 
} 

Task waiter = Task.WhenAll(tasks); 
try 
{ 
    waiter.Wait(); 
} 
catch {} 

if (waiter.Status == TaskStatus.RanToCompletion) 
{ 
    Console.WriteLine("All messages sent."); 
} 
else 
{ 
    Console.WriteLine("Some messages failed to send."); 
} 
+0

War ein bisschen schnell, dies zu akzeptieren. habe deine Lösung versucht und es funktioniert nicht. Ich verwende die SendAsync-Methode des smptp-Clients, und der obige Code wird ausgeführt, bevor die Nachrichten tatsächlich gesendet werden. – ThunD3eR

+1

@ Ra3IDEn Der obige Code ist ein Beispiel dafür, wie man das macht, was man will. Sie haben nie angegeben, dass die Methoden in Ihrer Frage "async" waren, und stellen Sie in Zukunft eine [MCVE] bereit. Da ich keine Ahnung habe, wie der Rest Ihres Codes aussieht, ist dies ein Beispiel dafür, wie Sie dies tun können, ich bin sicher, dass Sie es an Ihre eigenen Bedürfnisse anpassen können. Wie hier oft erwähnt, ist dies kein Code-Schreibdienst. – TheLethalCoder

+0

Niemals einen Code-Service für diese m8 erwartet. War wie ich in der Frage gefragt habe nach einem Weg zu suchen, ob alle meine Threads erledigt sind. Ich dachte nicht, dass ich mehr Code brauchte, als was ich zur Verfügung stellte – ThunD3eR

-3

können Sie statischen Wert haben:

public static int ThreadCount = 0; 

und jedes Mal, wenn neuen Thread Erhöhung Wert dieser Variablen um 1 laichen, tun Gegenteil, wenn Thread „fertig“ ist oder Beenden und Wert um 1 verringern.

Wenn ThreadCount ist == 0 wissen Sie, dass keine Threads am Leben sind, dh. alles fertig.

Sie können auch Logik für das System schreiben, um diese Variable zu beobachten, und wenn sie steigt, wissen Sie, dass der Thread zu arbeiten begonnen hat.

Ich hoffe, das hilft Ihnen.

+0

Das funktioniert vielleicht, aber es ist eine schreckliche Lösung für ein Problem, das sich leicht lösen lässt. Ganz zu schweigen von der ganzen Sperrung, die du machen musst usw. – TheLethalCoder

+0

Ich habe das als meinen ersten Versuch gemacht, der funktioniert, aber das, was ich mir erhofft habe, ist, ob es einen globalen Parameter gibt, der das für mich hält. Wenn es einen boolean gibt, der getS an/aus schaltet, wenn es keine Threads mehr gibt – ThunD3eR

+0

@TheLethalCoder Ja, ich weiß, das ist ein schrecklicher Weg, es zu tun, das macht es nicht "schlecht". –

Verwandte Themen