Web应用中await后代码无法执行的问题求助
异步代码中await后代码不执行的排查求助
我已经调试这个问题一周了,始终找不到await之后的代码不执行的原因。查资料说这种情况一般是await的任务没完成,但实际任务返回了Task completed="0"。
我要实现三个功能:
- 打开.CSV文件并将数据保存到数据库(此功能正常)
- 发送邮件通知文件上传成功(此功能正常)
- 在页面的ListView中显示上传和邮件发送的结果(如文件名、邮件发送成功等)——这部分代码从未执行
我试了两种写法,结果完全一样。相关的await代码如下:
public async Task<string[]> AutomaticFileUploadAsync() { // 上传文件数据到数据库的代码已省略 // // 创建DataTable并添加数据的代码已省略 // // 发送所有邮件 // errorClass.writeToDebugLogFile("About to Send Email. point 2", DateTime.Now.ToString()); Task<string[]> task1 = AutoUploadedBookingFileEmailingCodeAsync(fileUploadDetails); await Task.WhenAll(task1); CompletedEmailTask = task1.Result; /*Task<string[]> completedTask = AutoUploadedBookingFileEmailingCodeAsync(fileUploadDetails); CompletedEmailTask = await completedTask; // completedTask = 0表示完成(正常), completedTask = 1表示错误, completedTask = 2表示已取消 // 在此处处理CompletedEmailTask // */ errorClass.writeToDebugLogFile("Just sent Email(s). point 2a", DateTime.Now.ToString()); }
调试日志能记录到"About to Send Email. point 2",但永远不会记录"Just sent Email(s). point 2a",后续更新ListView的代码也不会执行。
UPDATE1:
之前省略了部分代码,以下是从邮件发送入口到实际异步发送的多层调用代码:
首先是邮件发送入口方法:
public async Task<string[]> AutoUploadedBookingFileEmailingCodeAsync(string[,] fileUploadStatus) { int arrayGetLength = fileUploadStatus.GetLength(0); // 数组第一维度长度 string[] completedTask = new string[2]; string[] completedTaskResults = new string[arrayGetLength]; // 发送邮件 for (int i = 0; i < arrayGetLength; i++) { string localResKeyID = fileUploadStatus[i, 4]; // 获取reservationID if (localResKeyID != "") { completedTask = await SendHTMLEmailAsync(localResKeyID, localEmailType); } else { completedTask[0] = "1"; } completedTaskResults[i] = completedTask[0]; } return completedTaskResults; }
接着是SendHTMLEmailAsync方法:
protected async Task<string[]> SendHTMLEmailAsync(string bookingRef, int emailType) { string[] taskException = new string[2]; try { string imageName1 = ""; // 为简化已移除 string imageName2 = ""; // 为简化已移除 string imageName3 = ""; // 为简化已移除 string imageName4 = ""; // 为简化已移除 string imageName5 = ""; // 为简化已移除 string imageSource1 = "\\htm\\images\\" + imageName1; string imageSource2 = "\\htm\\images\\" + imageName2; string imageSource3 = "\\htm\\images\\" + imageName3; string imageSource4 = "\\htm\\images\\" + imageName4; string imageSource5 = "\\htm\\images\\" + imageName5; string serverLink = (Server.MapPath("") + "\\htm\\"); taskException = await EmailClass.SendBookingHTMLEmailAsync(imageSource1, imageSource2, imageSource3, imageSource4, imageSource5, bookingRef, serverLink, emailType); } catch (Exception ex) { // 写入错误日志 ex.Message.ToString(); } return taskException; }
然后是SendBookingHTMLEmailAsync方法:
public async Task<string[]> SendBookingHTMLEmailAsync(string imageSource1, string imageSource2, string imageSource3, string imageSource4, string imageSource5, string bookingRef, string serverLink, int emailType) { var mail = new MailMessage(from, to); string[] taskExceptionEmail = new string[3]; // 为简化已移除超过2000行代码 taskExceptionEmail = await EmailServCs.SendMailUsingAsync(mail); return taskExceptionEmail; }
最后是SendMailUsingAsync方法:
public async Task<string[]> SendMailUsingAsync(MailMessage mailMessage) { string mailSettingsSection = "mailSettings/Ionos"; // 创建新数组存储任务结果 string[] completedTask = new string[3]; // 用默认数据填充数组 completedTask[0] = "99"; completedTask[1] = "99"; completedTask[2] = "99"; // 设置是否启用SSL安全 bool enableSSL = true; try { if (sendEmails == true) // 调试时用于阻止邮件发送 { SmtpSection SmtpSection = (SmtpSection)ConfigurationManager.GetSection(mailSettingsSection); // 设置使用web.config中的哪个smtp邮件配置节 mailMessage.IsBodyHtml = true; using (var smtpClient = new SmtpClient(SmtpSection.Network.Host, SmtpSection.Network.Port)) // 从Web.config获取主机和端口 { smtpClient.Credentials = new NetworkCredential(SmtpSection.Network.UserName, SmtpSection.Network.Password); // 从Web.config获取发送账户的用户名和密码 smtpClient.EnableSsl = enableSSL; smtpClient.Timeout = 30000; Task task = smtpClient.SendMailAsync(mailMessage); // 创建新任务记录结果 await task.ConfigureAwait(false); // 为任务设置等待器 smtpClient.Dispose(); if (task.IsFaulted == true) { completedTask[0] = "1"; string TaskExceptionMsg = task.Exception.Message; completedTask[1] = TaskExceptionMsg; } else if (task.IsCanceled == true) { completedTask[0] = "2"; string TaskExceptionMsg = task.Exception.Message; completedTask[1] = TaskExceptionMsg; } else if (task.IsCompleted == true) { completedTask[0] = "0"; completedTask[1] = "Sent Ok"; } else { // 发生其他情况 completedTask[0] = "error"; completedTask[1] = "error"; } } } } catch (Exception ex) { // 写入错误日志 ex.message } return completedTask; }
希望这些信息能帮助排查问题,恳请各位提供帮助。
内容的提问来源于stack exchange,提问作者FlashTrev
相关产品推荐
相关产品推荐

