我有一个应用程序,在调用rest Web服务时可以使用Async和Await。运行单元测试时,即使正在使用等待,我似乎也无法获得任何正确的响应。这是异步方法:
public async Task<Response> SendEmail(string apiKey, string senderEmail, string senderName, string recipientEmail, string recipientName, string subject, string content, bool html)
{
var client = new SendGridClient(apiKey);
var from = new EmailAddress(senderEmail, senderName);
var to = new EmailAddress(recipientEmail, recipientName);
var msg = MailHelper.CreateSingleEmail(from, to, subject, html ? null : content, html ? content : null);
var response = await client.SendEmailAsync(msg);
return response;
}
调用方法如下:
public static object SendEmail(string apiKey, string senderEmail, string senderName, string recipientEmail, string recipientName, string subject, string content, bool html)
{
EmailHandler emailHandler = new EmailHandler();
var response = emailHandler.SendEmail(apiKey, senderEmail, senderName, recipientEmail, recipientName, subject, content, html);
return response;
}
现在,如果我在调用函数的返回响应上放置一个断点,则可以看到状态为“等待激活”和结果为“尚未计算”的对象。我所能收集到的东西,在返回的对象上调用.Result应该使它同步运行并返回结果。 (例如,请求的状态码,例如200)。
我在这里想念什么?为什么不等到完成?
答案 0 :(得分:5)
async-await只是关键字,它们告诉编译器将您的代码作为IAsyncStateMachine
的实现进行编译并等待其完成,这两个关键字需要结合使用才能起作用,并且它们仅在Task
对象上工作。 Task
代表正在进行的工作。
您必须将SendEmail
方法标记为async
,将返回类型更改为Task<object>
,然后将await
更改为emailHandler.SendEmail
调用。
最重要的是,如果您要async
走,那么您必须一直走async
,一直走上,然后await
在某些或许多点上,否则您将开始着眼于同步运行异步代码,这简直让您无所适从。
public static async Task<object> SendEmail(string apiKey, string senderEmail, string senderName, string recipientEmail, string recipientName, string subject, string content, bool html)
{
EmailHandler emailHandler = new EmailHandler();
var response = await emailHandler.SendEmail(apiKey, senderEmail, senderName, recipientEmail, recipientName, subject, content, html);
return response;
}
与往常一样,Stephen Cleary是async
知识的绝佳来源。
答案 1 :(得分:2)
这是因为
var response = emailHandler.SendEmail(apiKey, senderEmail, senderName, recipientEmail, recipientName, subject, content, html);
初始化一个任务,而您的调用者(公共静态对象SendEmail)不会等待该任务。
克里斯·普拉特(Chris Pratt)编写了一个带有异步帮助器的nice blog,以运行异步方法同步。
答案 2 :(得分:-4)
在我看来,您希望SendEmail是同步的。您可以像这样在SendEmail中等待异步方法完成:
public static Response SendEmail(string apiKey, string senderEmail, string senderName, string recipientEmail, string recipientName, string subject, string content, bool html)
{
EmailHandler emailHandler = new EmailHandler();
var responseTask = emailHandler.SendEmail(apiKey, senderEmail, senderName, recipientEmail, recipientName, subject, content, html);
responseTask.Wait(); // Wait for the task to complete
return responseTask.Result;
}