我有一个像这样的异步方法:
public static async Task<bool> SendMailAsync(){
...something
}
此方法返回结果的时间很长。
我还有其他方法:
public async Task<string> ThisIsController(){
Task<bool> result = SendMailAsync();
OtherMethod1();
OtherMethod2();
....
}
我没有在结果中使用await。但是“ThisIsController”总是等待结果返回然后运行OtherMethod1(),OtherMethod2? 谢谢
UPDATE1: 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;
}
}
答案 0 :(得分:3)
添加async
方法不(单独使用)使代码异步。异步代码是 hard - async
修饰符所做的就是启用await
关键字(并启用一些关于返回类型的编译器魔法)。如果该方法实际上没有异步执行任何操作,则不会异步。特别是:
await
:它在async
意义上真的不同步
async
,而只是来自另一个return
sa 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, 也可以通过延迟异步使异步:
foreach (var email in sendingList)
{
MailHelper.SendMail(email, subject, body);
await Task.Delay(60 * 1000);
}
最后的想法:隐藏异常细节几乎总是不好。
答案 1 :(得分:2)
SendMailAsync将同步运行,直到第一次等待阻止。
将标记方法标记为“异步”实际上并不能神奇地以异步方式运行。你必须在该方法中使用等待
您的代码是同步的,可以在另一个线程中运行它,而无需更改您可以使用的SendMailAsync中的签名或代码。但理想情况下,您应该重写SendMailAsync以使用MailSender的异步API
var resultTask = Task.Run(async () => await SendMailAsync());
OtherMethod1();
OtherMethod2();
var result = await resultTask;
答案 2 :(得分:0)
如果你等待一个OtherMethod1(),他们将等待Method完成,然后他将执行OtherMethod2()。但是,如果你不等待它可能是Method1没有完成,Method2将启动。这取决于Method1和2中的内容。
答案 3 :(得分:0)
有几个后台作业处理库。我的一些项目使用了hangfire。
但是如果你想简化这个,你可以使用asp.net内置的东西。
HostingEnvironment.QueueBackgroundWorkItem((ct) =>
{
SendMailAsync();
});
OtherMethod1();
OtherMethod2();
确保添加对System.Web.Hosting的引用
您不需要SendMailAsync()来返回任务,因为您不会等待某事。只需发送电子邮件代码即可在后台运行。