キュー内の多数の電子メールを処理するWindowsサービスを継承しました。単純に聞こえる、キューをつかむ、SmtpClient.SendAsyncがコールバックからエラーを返さない場合、送信されたとしてDBの電子メールにフラグを立てる..私はセマフォを使用しているため、 SMTPクライアントのAsync Sendメソッドを呼び出すことができます。これはステータスを取得する唯一の方法であり、別の呼び出しを非同期にする前に、Microsoftのドキュメントごとに操作を終了する必要があります。今は楽しい部分のために。私はParallel.ForEachを使用して、彼のようにキューを取得することにしました。このメソッドは、WindowsサービスのOnStartで呼び出されます。私は別のスレッドでこのメソッドを呼び出そうとしましたが、同じ結果を得ることに注意してください。Parallel.ForEachループ内から非同期メソッドを呼び出す際の操作の例外が無効です
私は、スレッドの知識が不足しているために、何かが分かりにくいと思っています。可能性が高いA.
private static void ProcessEmailQueue()
{
List<EmailQueue> emailQueue =
_repository.Select<EmailQueue>().Where(x => x.EmailStatuses.EmailStatus == "Pending").ToList();
Parallel.ForEach(emailQueue, message =>
{
_smtpMail.FromAddress = message.FromAddress;
_smtpMail.ToAddress = message.ToAddress;
_smtpMail.Subject = message.Subject;
_smtpMail.SendAsHtml = message.IsHtml > 0;
_smtpMail.MessageBody = message.MessageBody;
_smtpMail.UserToken = message.EmailQueueID;
bool sendStatus = _smtpMail.SendMessage();
// THIS BLOWS UP with InvalidOperation Exception
});
}
ここでループを使用して呼び出されているSMTPメソッドがあります。
public bool SendMessage()
{
mailSendSemaphore = new Semaphore(0, 10); // This is defined as private static Semaphore mailSendSemaphore;
try
{
var fromAddress = new MailAddress(FromAddress);
var toAddress = new MailAddress(ToAddress);
using (var mailMessage = new MailMessage(fromAddress, toAddress))
{
mailMessage.Subject = Subject;
mailMessage.IsBodyHtml = SendAsHtml;
mailMessage.Body = MessageBody;
Envelope = mailMessage;
smtp.SendCompleted += smtp_SendCompleted;
smtp.SendAsync(mailMessage, UserToken);
mailSendSemaphore.WaitOne();
return _mailSent;
}
}
catch (Exception exception)
{
_logger.Error(exception);
return _mailSent;
}
}
SMTPのCALLBACKここ
private void smtp_SendCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Cancelled)
{
}
if (e.Error != null)
{
}
else
{
_mailSent = true;
}
mailSendSemaphore.Release(2);
}
を送る例外で、いくつかの奇妙な理由でそれを得るために、いくつかを取りました。
System.InvalidOperationException was unhandled by user code
メッセージ=非同期呼び出しはすでに進行中です。このメソッドを呼び出すには、完了またはキャンセルする必要があります。 は、Source =システム のStackTrace:System.Net.Mail.SmtpClient.SendAsyncで (はMailMessageメッセージはUserTokenオブジェクト) DFW.Infrastructure.Communications.SmtpMail.SendMessageで()SmtpMail.cs中:EmaiProcessorService.EmailQueueServiceでライン71 .B_ 0(EmailQueueメッセージ)のService1.cs:行57 at System.Threading.Tasks.Parallel。 <は> C _DisplayClass2d 2.<ForEachWorker>b__23(Int32 i) at System.Threading.Tasks.Parallel.<>c__DisplayClassf
1.b__c() のInnerException:
は今、私たちはエラーテキストを持っていること、それはそう、私のWAITONEさてSystem.Threading.Tasks.Parallel
InvalidOperationExceptionの*詳細*を渡してください。どのラインが例外を投げているのですか?メッセージは何ですか? –
私たちが話しているようにキャッチしようとすると、私はtry catchブロックのどれかでそれを得ることができないので、幾分埋め込まれているようだ。 – CrazyCoderz
Windowsサービスのデバッグはあまり面白くない:) – CrazyCoderz