sendasync 経由でメールを送信しようとしています。問題は、sendcompleted イベント ハンドラーに入らないように見えることです。そこにブレークポイントを追加しましたが、トリガーされません。プログラムは私のセマフォで待機するだけです。何か案は?プログラムは、Windows フォーム アプリです。
if (send)
{
print("Starting to send mail to " + Globalcls.projects[i].name);
mailSendSemaphore = new Semaphore(0, 1);
System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
msg.To.Add(Globalcls.projects[i].email);
msg.From = new MailAddress(Globalcls.settings.server_email);
msg.Subject = "Data";
msg.SubjectEncoding = System.Text.Encoding.UTF8;
msg.Body = "Please see attached data";
msg.BodyEncoding = System.Text.Encoding.UTF8;
msg.IsBodyHtml = false;
msg.Priority = MailPriority.High;
foreach (string fileName in files)
{
msg.Attachments.Add(new System.Net.Mail.Attachment(fileName));
}
SmtpClient client = new SmtpClient();
client.Credentials = new System.Net.NetworkCredential(Globalcls.settings.username, Globalcls.settings.password);
client.Port = Convert.ToInt32(Globalcls.settings.portS);//or use 587
client.Host = "smtp.xdsl.co.za";
client.SendCompleted += new SendCompletedEventHandler(MailSendCallback);
client.SendAsync(msg,null);
mailSendSemaphore.WaitOne();
// if (Globalcls.error_message != "")
// throw Exception
//client.Dispose();
print("email sent to " + Globalcls.projects[i].name);
client.Dispose();
mailSendSemaphore.Dispose();
msg.Dispose();
}
//Array.ForEach(Directory.GetFiles(GlobalClass.projects[i].foldero), delegate(string path) { File.Delete(path); });
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(Globalcls.projects[i].foldero);
foreach (System.IO.FileInfo file in directory.GetFiles()) file.Delete();
foreach (System.IO.DirectoryInfo subDirectory in directory.GetDirectories()) subDirectory.Delete(true);
}
これが私の onsendcomplete 偶数ハンドラーです
private static void MailSendCallback(object sender, AsyncCompletedEventArgs arg)
{
// oncomllete event for async send.
if (arg.Error != null)
Globalcls.error_message = arg.Error.ToString();
// Release the main thread
mailSendSemaphore.Release();
}
編集
sendasync を使用する理由は、send async が明らかにファイルのアップロードが完了するのを待っているからです。現在の問題は、添付ファイルが大きすぎて、アップロードにタイムアウトよりも時間がかかる場合があることです。タイムアウトを長くすることはできますが、どのくらい長くするべきかわかりません。ほとんどのメールは簡単に 3MB に達します。また、adsl 回線が常に最も安定しているわけではありません。
非同期送信を待機する理由は、クライアントごとに複数の送信を行うことができないためです。だからこそ完成を待ちます。
私の問題は、タイムアウトに関連しています。smtp と smtp クライアントの間に通信がない場合にのみタイムアウトになるタイムアウトが必要です。
編集2
これは私のコードが元々どのように見えるかです。その大規模なタイムアウトを回避したいと思います。マルチスレッドにすると、GUIがハングしなくなります。
if (send)
{
print("Starting to send mail to " + Globalcls.projects[i].name);
// mailSendSemaphore = new Semaphore(0, 1);
System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
msg.To.Add(Globalcls.projects[i].email);
msg.From = new MailAddress(Globalcls.settings.server_email);
msg.Subject = "Data";
msg.SubjectEncoding = System.Text.Encoding.UTF8;
msg.Body = "Please see attached data";
msg.BodyEncoding = System.Text.Encoding.UTF8;
msg.IsBodyHtml = false;
msg.Priority = MailPriority.High;
foreach (string fileName in files)
{
msg.Attachments.Add(new System.Net.Mail.Attachment(fileName));
}
SmtpClient client = new SmtpClient();
client.Credentials = new System.Net.NetworkCredential(Globalcls.settings.username, Globalcls.settings.password);
client.Port = Convert.ToInt32(Globalcls.settings.portS);//or use 587
// client.Host = "127.0.0.1";
client.Host = "smtp.xdsl.co.za";
client.Timeout = 400000;
client.Send(msg);
/* client.SendCompleted += new SendCompletedEventHandler(MailSendCallback);
client.SendAsync(msg,null);
mailSendSemaphore.WaitOne();*/
// if (Globalcls.error_message != "")
// throw Exception
print("email sent to " + Globalcls.projects[i].name);
client.Dispose();
//mailSendSemaphore.Dispose();
msg.Dispose();
}
//Array.ForEach(Directory.GetFiles(GlobalClass.projects[i].foldero), delegate(string path) { File.Delete(path); });
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(Globalcls.projects[i].foldero);
foreach (System.IO.FileInfo file in directory.GetFiles()) file.Delete();
foreach (System.IO.DirectoryInfo subDirectory in directory.GetDirectories()) subDirectory.Delete(true);
}
catch (Exception ex)
{
print("Error with " + Globalcls.projects[i].name);
print(ex.ToString());
timer1.Enabled = false;
timer1.Stop();
btn_start.Enabled = true;
string contents = "There was an error in sending mail to " + Globalcls.projects[i].name;
string heading = " Anxo error";
string subject = "Anxo error";
errormail(heading, subject, contents, ex.ToString(), Globalcls.projects[i].sos);
result = false;
}