【发布时间】:2021-01-20 02:04:15
【问题描述】:
我有一个 ac#WebApi 项目,用户可以在网站下订单,支付完成后的每个订单都会执行一个名为ConfirmOrder的函数,它将订单状态从STB更新为COMPLETED。
在如下函数中,如下所示:
public static void ConfirmOrder(string piva, string orderID, double importo = 0, string transazione = "", string paymentID = "", string tipo = "MENU")
{
string connectionString = getConnectionString(piva);
using var connection = new MySqlConnection(connectionString);
string query_menu = "QUERY";
string query_pagamenti = "QUERY";
using var cmd = new MySqlCommand(query_pagamenti, connection);
connection.Open();
cmd.Parameters.AddWithValue("@tipo", tipo.ToUpper());
cmd.Parameters.AddWithValue("@importo", importo);
cmd.Parameters.AddWithValue("@transazione", transazione);
cmd.Parameters.AddWithValue("@dataOra", DateTime.Now);
cmd.Parameters.AddWithValue("@orderID", orderID);
cmd.Parameters.AddWithValue("@paymentID", paymentID);
cmd.Prepare();
cmd.ExecuteNonQuery();
cmd.CommandText = query_menu;
cmd.ExecuteNonQuery();
if (!tipo.Equals("MENU"))
{
EmailHelper.SendRiepilogo(piva, int.Parse(orderID)); // SENDING SUMMARY MAIL
}
}
我正在调用另一个函数SendRiepilogo,它向用户和商店发送摘要,但在这种情况下,我不能等待该函数响应,但它必须自己执行而不卡住ConfirmOrder回调..所以我等不及要执行SendRiepilogo,此时我已经阅读了IHostingService,但我不知道如何将我的SendRiepilogo迁移到IHostingService并从ConfirmOrder运行它...
我的SendRiepilogo 看起来像这样:
public static async void SendRiepilogo(string piva, int idOrdine)
{
var order = GetOrdine(piva, idOrdine);
if (order == null)
{
return;
}
try
{
var negozio = getNegozio(order.idNegozio);
var from = new MailAddress("ordini@visualorder.it", "VisualOrder");
var to = new MailAddress(order.cliente.FirstOrDefault().email);
using MemoryStream ms = new MemoryStream();
QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode("vo/" + idOrdine, QRCodeGenerator.ECCLevel.Q);
Base64QRCode qrCode = new Base64QRCode(qrCodeData);
byte[] byteQr = Convert.FromBase64String(qrCode.GetGraphic(20));
MemoryStream streamQr = new MemoryStream(byteQr);
var qrImage = new LinkedResource(streamQr, MediaTypeNames.Image.Jpeg)
{
ContentId = "qrImage"
};
string nome = order.cliente.FirstOrDefault().nome;
var orderEmail = new { idOrdine, order, nome, negozio };
byte[] byteLogo = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(negozio.logo));
MemoryStream streamLogo = new MemoryStream(byteLogo);
var logoImage = new LinkedResource(streamLogo, MediaTypeNames.Image.Jpeg)
{
ContentId = "logoImage"
};
string template = File.ReadAllText("Views/Emails/EmailRiepilogo.cshtml");
var htmlBody = Engine.Razor.RunCompile(template, "riepilogo", null, orderEmail);
AlternateView alternateView = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html);
alternateView.LinkedResources.Add(qrImage);
alternateView.LinkedResources.Add(logoImage);
var message = new MailMessage(from, to)
{
Subject = "Riepilogo ordine",
Body = htmlBody
};
message.IsBodyHtml = true;
message.AlternateViews.Add(alternateView);
using var smtp = new SmtpClient("smtps.aruba.it", 587)
{
EnableSsl = true,
Credentials = new NetworkCredential("XXX", "XXX")
};
await smtp.SendMailAsync(message); // sending email to user
await smtp.SendMailAsync(MessageNegozio(order, idOrdine, negozio)); // sending email to shop
}
catch (Exception e)
{
return;
}
ConfirmEmail(piva, idOrdine); // setting "EMAIL SENT" flag in DB to true
return;
}
【问题讨论】:
-
你试过了吗
Task.Run(() => SendRiepilogo())stackoverflow.com/a/17805992/575468 -
@dreijntjens 我收到了
An asynchronous call is already in progress. It must be completed or canceled before you can call this method.,我已经从 smtp.SendMailAsync 中删除了 await 并让函数不异步执行Task.Run -
@dreijntjens 在执行 Task.Run 时我应该保留
await和async吗? -
不要混合使用异步和同步,如果不是 EventHandler,不要使用
async void(极少数例外)。 -
您无法使用
Task.Run解决此问题。后台服务是完全不同的服务,使用自己的线程。你必须告诉它该做什么并让它完成工作。顺便说一句,这就是文档显示的内容
标签: c#