我有一个像这样的异步方法:
public static async Task<bool> SendMailAsync()
{
// ...something
}
这个方法返回结果的时间很长。
我还有其他类似的方法:
public async Task<string> ThisIsController()
{
Task<bool> result = SendMailAsync();
OtherMethod1();
OtherMethod2();
// ....
}
我没有在结果中使用await。但是
ThisIsController
总是等待结果返回然后运行OtherMethod1()
,OtherMethod2
?
谢谢你
更新1:
SendMailAsync()
的完整代码:
public static async Task<bool> SendMailAsync(List<string> listEmail, string subject, string body)
{
try
{
var emailsPerMin = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["EmailsPerMin"]
.ToString());
for (int i = 1; i <= System.Math.Ceiling(listEmail.Count * 1.0 / emailsPerMin); i++)
{
List<string> sendingList = listEmail.Skip((i - 1) * emailsPerMin).Take(emailsPerMin).ToList();
foreach (var email in sendingList)
{
MailHelper.SendMail(email, subject, body);
Thread.Sleep(60 * 1000);
}
}
return true;
}
catch
{
return false;
}
}
添加
async
方法不会(本身)使代码异步。异步代码是 hard - async
修饰符所做的就是启用 await
关键字(并启用一些有关返回类型的编译器魔法)。如果该方法实际上没有执行任何异步操作,那么它就不是异步的。特别是:
await
:从 async
的意义上来说,它并不是真正的异步
async
,并且只是return
是来自另一个方法的
Task[<T>]
,那么它可能会暴露异步行为)await
,但所有正在等待的事情实际上总是同步完成的:它并不是真正的异步在本例中,这是第一颗子弹。代码中没有
await
。事实上,编译器应该已经向您发出警告:
Warning CS1998 This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
即使一个方法返回
Task[<T>]
(或其他可等待模式):如果它不是 实际上 异步(因为上面的任一项目符号):它将在返回到调用者之前运行到完成;当它这样做时,它就会被认为已经完成。
要使此代码异步,(大概是发送)需要异步。也许:
foreach (var email in sendingList)
{
await MailHelper.SendMailAsync(email, subject, body);
await Task.Delay(60 * 1000);
}
注意;如果您的
MailHelper
没有
async
API,您 也可以只需将 delay 设为异步即可使其异步:
foreach (var email in sendingList)
{
MailHelper.SendMail(email, subject, body);
await Task.Delay(60 * 1000);
}
最后的想法:隐藏异常细节几乎总是不好的。
将方法标记为“异步”实际上并不能使其神奇地异步运行。你必须在该方法中使用await
您的代码是同步的,可以在另一个线程中运行它,而无需更改您可以使用的 SendMailAsync 中的签名或代码。但理想情况下,您应该重写 SendMailAsync 以使用 MailSender 的异步 API
var resultTask = Task.Run(async () => await SendMailAsync());
OtherMethod1();
OtherMethod2();
var result = await resultTask;
但是如果你想让这变得简单,你可以使用 asp.net 中内置的东西。
HostingEnvironment.QueueBackgroundWorkItem((ct) =>
{
SendMailAsync();
});
OtherMethod1();
OtherMethod2();
确保添加对 System.Web.Hosting 的引用
您不需要 SendMailAsync() 来返回任务,因为您不会等待某些事情。只需让电子邮件代码的发送在后台运行即可。