我有一个通过接收短信发送电子邮件的应用程序。我意识到这段代码smt.Send(mailMsg);
我的UI冻结,直到发送过程完成,这有时需要2-5分钟,我不希望用户认为应用程序已崩溃或出现故障。因此,我想知道如何在后台工作程序中运行该方法,以避免冻结我的UI。以下是相关代码谢谢。
报告生成/导出方法
private void Q4report()
{
Control.CheckForIllegalCrossThreadCalls = false;
Output("Processing request...");
ReportDocument cryRpt1 = new ReportDocument();
cryRpt1.Load("cryQ2.rpt");
crystalReportViewer2.ReportSource = cryRpt1;
crystalReportViewer2.Refresh();
cryRpt1.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, "QueryReport.pdf");
Output("Generating report...");
Output("Report Process Completed");
if (i != 1)
{
sendMail("QueryReport.pdf", "4POS StockItem/per price list Query Report");
}
else if( i == 1)
{
Unsent_Request_sendMail("QueryReport.pdf", "4POS StockItem/per price list Query Report");
}
}
电子邮件发送方式
public bool sendMail(string pdf, string subject)
{
bool flag = false;
MailMessage mailMsg = new MailMessage();
try
{
// To
mailMsg.From = new MailAddress(radtxtEmail.Text);
if (sub3 != null)
{
string strSubject = subject;
string strBody = "Kindly find attached your query report.";
mailMsg.To.Add(sub3);
mailMsg.Subject = strSubject;
mailMsg.Body = strBody;
Attachment attachment = new Attachment(pdf);
mailMsg.Attachments.Add(attachment);
mailMsg.IsBodyHtml = true;
using (SmtpClient smt = new SmtpClient("smtp.gmail.com"))
{
smt.Port = 587;
smt.Credentials = new System.Net.NetworkCredential(radtxtEmail.Text, radtxtboxPassword.Text);
smt.EnableSsl = true;
bool connection = NetworkInterface.GetIsNetworkAvailable();
bool IsOnline = ModemManager.netCheck.IsOnline();
if (connection == true)
{
if (IsOnline == true)
{
smt.Send(mailMsg);
sent_insert();
mailMsg.Dispose();
attachment.Dispose();
Output("Report Mail successfully sent!");
}
else
{
Output("Internet Access Unavailable.");
Output("Mail process terminated.");
Unsent_insert();
mailMsg.Dispose();
attachment.Dispose();
// btnSendMessage_Click();
return false;
}
}
else
{
Output("Network Connectivity Unavailable.");
Unsent_insert();
mailMsg.Dispose();
attachment.Dispose();
// btnSendMessage_Click();
return false;
}
}
flag = true;
}
}
catch (Exception ex)
{
Output(ex.Message);
}
return flag;
}
答案 0 :(得分:2)
您可以将sendMail方法封装在Task.Run块中,该块将在单独的线程上启动该方法:
Ext.override(Ext.form.field.Base, {
initEvents: function() {
var me = this,
inputEl = me.inputEl,
onFieldMutation = me.onFieldMutation,
events = me.checkChangeEvents,
len = events.length,
i, event;
if (inputEl) {
me.mon(inputEl, Ext.supports.SpecialKeyDownRepeat ? 'keydown' : 'keypress', me.fireKey, me);
for (i = 0; i < len; ++i) {
event = events[i];
if (event === 'propertychange') {
me.usesPropertychange = true;
}
if (event === 'textInput') {
me.usesTextInput = true;
}
me.mon(inputEl, event, onFieldMutation, me);
}
}
me.callParent();
},
bindPropertyChange: function(active) {
var method = active ? 'resumeEvent' : 'suspendEvent',
inputEl = this.inputEl;
if (this.usesPropertychange) {
inputEl[method]('propertychange');
}
if (this.usesTextInput) {
inputEl[method]('textInput');
}
}
});
请注意,除非您保存创建的任务,否则您将无法监控任务的完成状态,或在需要时取消它。如果这是用于UI,我将捕获创建的任务作为父类状态的一部分:
if (i != 1)
{
Task.Run(() => sendMail("QueryReport.pdf", "4POS StockItem/per price list Query Report"));
}
然后附加从Task.Run创建的任务,以便在需要时有办法返回生成的任务:
private Task sendMailTask;
或者,如果由于按钮单击而触发此操作,则可以在异步void方法中等待它:
if (i != 1)
{
this.sendMailTask = Task.Run(() => sendMail("QueryReport.pdf", "4POS StockItem/per price list Query Report"));
}
仍会将控制权返回给用户界面并运行后台发送邮件的工作。
答案 1 :(得分:1)
使用BackgroundWorker防止冻结