22 Stimmen

Warum kann SmtpClient.SendAsync nur einmal aufgerufen werden?

Ich versuche, einen Benachrichtigungsdienst (für völlig legit nicht-Spam Zwecke) in .NET mit SmtpClient zu schreiben. Ursprünglich habe ich nur in einer Schleife durch jede Nachricht gesendet, aber das ist langsam und ich möchte die Geschwindigkeit zu verbessern. Also bin ich zu 'SendAsync' übergegangen, aber jetzt bekomme ich beim zweiten Aufruf den folgenden Fehler:

An asynchronous call is already in progress. 

Ich habe das so verstanden, dass MS System.Net.Mail verkrüppelt hat, um Massenmailer zu verhindern. Ist das richtig? Wenn ja, gibt es eine bessere Möglichkeit, dies in .NET zu tun und trotzdem in der Lage zu sein, die Ergebnisse jeder E-Mail zu protokollieren (was für unseren Kunden wichtig ist). Wenn nicht, warum kann SendAsync nur einmal aufgerufen werden?

36voto

Darin Dimitrov Punkte 990883

Nach Angaben der Dokumentation :

Nach dem Aufruf von SendAsync müssen Sie warten warten, bis die E-Mail-Übertragung abgeschlossen ist, bevor Sie versuchen, eine eine weitere E-Mail-Nachricht mit Send oder SendAsync.

Um mehrere Mails gleichzeitig zu versenden, benötigen Sie also mehrere SmtpClient-Instanzen.

0 Stimmen

Hat nicht jemand bereits einen solchen Mechanismus implementiert, um mehrere E-Mails auf einmal zu senden? auf der smtp-Client-Klasse? klingt wie ein Problem viele Menschen begegnen... irgendwie seltsam, dass niemand jemals einen Rahmen für es erstellt.

3 Stimmen

@ItayLevin Ich sehe keine Notwendigkeit für den Versuch, die SmtpClient-Instanz wiederverwenden. Warum nicht einfach jede Instanz für jeden E-Mail-Versandversuch widmen, wie Darin es fachmännisch erklärt.

0 Stimmen

Dies ist eine guter Beitrag zu diesem Thema.

6voto

kntcnrg Punkte 593

Möglicherweise können Sie Folgendes verwenden:

ThreadPool.QueueUserWorkItem(state => client.Send(msg));

Dies sollte es ermöglichen, dass Ihre Nachrichten in eine Warteschlange gestellt und gesendet werden, sobald Threads verfügbar sind.

6 Stimmen

Diese Umsetzung kann immer noch zu einem System.InvalidOperationException wenn sie von der gleichen SmtpClient Instanz.

5voto

Tamas Czinege Punkte 114595

Dies ist natürlich kein Versuch, Massenversender zu stoppen.

Der Grund dafür ist, dass die SmtpClient-Klasse nicht thread-sicher ist. Wenn Sie mehrere E-Mails gleichzeitig senden möchten, müssen Sie einige Worker-Threads erstellen (es gibt mehrere Möglichkeiten, dies im .NET Framework zu tun) und in jedem dieser Threads eine eigene Instanz von SmtpClient erstellen.

5voto

Gant Punkte 29313

Ich glaube, Sie missverstehen die XXXAsync Klasse von Methoden. Der Zweck dieser asynchronen Aufrufe besteht darin, dass das Programm weiterlaufen kann, ohne dass die Methode die Verarbeitung beenden und zuerst zurückkehren muss. Sie können dann später mit dem Ergebnis fortfahren, indem Sie etwas abonnieren wie XXXReceived Ereignis des Objekts.

Um mehr als eine E-Mail gleichzeitig zu versenden, können Sie mehrere Thread s.

2 Stimmen

Mehrere Threads, die SendAsync aufrufen, sind genau die Ursache für diese Ausnahme

0 Stimmen

@statichippo Der OP hat die asynchrone Version von send mail gar nicht verwendet. Ich habe vorgeschlagen, mehrere Threads mit nicht asynchronem Aufruf zu verwenden.

3 Stimmen

Wenn Sie Send (non-async) in mehreren Threads aufrufen, erhalten Sie eine Ausnahme. Die SmtpClient-Klasse ist nur in der Lage, 1 Nachricht zu einem Zeitpunkt zu senden, unabhängig davon, wie viele Threads es senden. Es ist ein Protokoll Problem, nicht ein C# Problem wirklich... Sie müssen warten, bis eine Nachricht gesendet wurde, bevor Sie eine weitere senden - unabhängig davon, ob Sie SendAsync oder Send verwenden. Es sei denn, Sie wollen mehrere SmtpClients erstellen

2voto

Colby Africa Punkte 1346

Sie können pro SMTP-Client immer nur einen Versand durchführen. Wenn Sie mehr als einen Sendeaufruf tätigen möchten, erstellen Sie mehr als einen SMTP-Client.

HTH,

Colby Afrika

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X