所以我有很多代碼在一個按鈕上運行。更新 excel 檔案,將郵件發送到郵件地址串列,將 excel 重新加載到 datagridview 中,清除串列框和文本框,在文本檔案中寫入日志文本行,禁用某些 UI。
現在我已經拆分了重新加載的 excel 檔案并在用戶額外的 OK 按鈕上寫入日志。這有點幫助。但仍然使程式在發送郵件和更新 excel 時無回應。
我不認為更新excel是問題。它就像平均大約 10 行中的 1 個特定單元格。
但問題似乎是郵件發送。如果郵件已經發送并且這里的郵件服務器很慢,它會等待確認。
我的郵件發送代碼是這個
SmtpClient smtpClient = new SmtpClient();
MailMessage message = new MailMessage();
If (System.IO.File.Exists(emailfile)
{
String[] Lines = System.IO.File.ReadAllLines(emailfile);
Foreach (string line in Lines)
message.To.Add(line);
}
Else
{ System.IO.File.WriteAllText(emailfile,"");
TextWriter Email = new StreamWriter(emailfile, true);
Email.Writeline("[email protected]");
Email.close();
}
try
{
MailAdress fromAddress = new MailAddress("[email protected]","order");
smtpClient.Host "";
smtpClient.Port xx;
smtpClient.credentials = ("""");
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
message.From = fromAddress;
message.Subject = "";
message.IsBodyHtml = True;
message.Body = Mybody();
message.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
smtpClient.Send(message);
}
Catch (exception)
{
MessageBox.Show("mail error");
}
我讀過一些關于 SendAsyc 的東西,我也讀過一些關于 task.run 或 task.factory.startnew 的東西還有 backgroundworker。
我不明白我應該使用哪一個以及如何實作它。
我確實需要 UI 等待(但不會無回應)發送郵件,并在郵件完成或失敗時給出一個訊息框。
uj5u.com熱心網友回復:
使用異步代碼看起來像
public async void OnButtonPress(){
try{
await SendEmail();
}
Catch (exception)
{
MessageBox.Show("mail error");
}
}
private async Task SendEmail(){
...
await smtpClient.SendMailAsync(...);
}
這是相當安全的,因為您的所有代碼都將在 UI 執行緒上運行。一個潛在的缺點是某些 *Async 方法是騙子,并且在 UI 執行緒上做了大量作業,因此可能無法完全解決阻塞問題。這種方法也不適用于 CPU 密集型代碼。因此,您可能需要對此進行測驗,看看它是否能解決您的問題。
另一種選擇是在后臺執行緒上同步運行代碼
public async void OnButtonPress(){
try{
await Task.Run(SendEmail);
}
Catch (exception)
{
MessageBox.Show("mail error");
}
}
private void SendEmail(){
// do work
}
此方法最大的缺點是該SendEmail方法無法訪問任何 UI 物件,并且其他共享資料結構可能需要被鎖保護。我建議在做任何涉及多執行緒的事情之前先閱讀一些關于執行緒安全的知識。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/504302.html
