【发布时间】:2016-05-24 03:19:49
【问题描述】:
我是 TAP 的新手,并且在 C# 的实践中使用 async/await,所以我可能在这里有一些不好的代码味道,所以要温柔。 :-)
我有一个如下所示的服务方法:
public OzCpAddOrUpdateEmailAddressToListOutput AddOrUpdateEmailAddressToList(
OzCpAddOrUpdateEmailAddressToListInput aParams)
{
var result = new OzCpAddOrUpdateEmailAddressToListOutput();
try
{
var mailChimManager = new MailChimpManager(aParams.MailChimpApiKey);
Task<Member> mailChimpResult =
mailChimManager.Members.AddOrUpdateAsync(
aParams.Listid,
new Member
{
EmailAddress = aParams.EmailAddress
});
//Poll async task until it completes.
//Give it at most 8 seconds to do what it needs to do
var outOfTime = DateTime.Now.AddSeconds(8);
while (!mailChimpResult.IsCompleted)
{
if (DateTime.Now > outOfTime)
{
throw new Exception("Timed out waiting for MailChimp API.");
}
}
//Should there have been a problem with the call then we raise an exception
if (mailChimpResult.IsFaulted)
{
throw new Exception(
mailChimpResult.Exception?.Message ??
"Unknown mail chimp library error.",
mailChimpResult.Exception);
}
else
{
//Call to api returned without failing but unless we have
//the email address subscribed we have an issue
if (mailChimpResult.Result.Status != Status.Subscribed)
{
throw new Exception(
$"There was a problem subscribing the email address
{aParams.EmailAddress} to the mailchimp list id
{aParams.Listid}");
}
}
}
catch (Exception ex)
{
result.ResultErrors.AddFatalError(PlatformErrors.UNKNOWN, ex.Message);
}
return result;
}
但是当我从 MVC 控制器 调用时,动作 mailChimpResult.IsCompleted 总是返回 false,最终我遇到了超时。
我意识到这是因为我没有按照 HttpClient IsComplete always return false 链接异步调用,并且由于线程不同,这种行为是“预期的”。
但是,我希望我的服务方法隐藏它正在做的事情的 async 性质的复杂性,并且只在我的操作方法中执行看似同步调用的操作:
var mailChimpResult =
_PlatformMailChimpService.AddOrUpdateEmailAddressToList(
new OzCpAddOrUpdateEmailAddressToListInput
{
EmailAddress = aFormCollection["aEmailAddress"],
Listid = ApplicationSettings.Newsletter.MailChimpListId.Value,
MailChimpApiKey = ApplicationSettings.Newsletter.MailChimpApiKey.Value
});
if (mailChimpResult.Result == true)
{
//So something
}
【问题讨论】:
-
你需要一直做
async。 “隐藏”它总是会导致痛苦的发现——通常是deadlock。基本上没有办法解决它。 -
@AlexeiLevenkov 但由于我的服务调用没有返回异步句柄等,我应该如何实现这一点。你能根据我的代码给我一个例子吗?
-
您在服务调用中隐藏了它。你需要
await调用AddOrUpdateAsync,而不是轮询它——这是大代码的味道。然后你可以使服务方法异步并在控制器中等待。
标签: c# asp.net-mvc asynchronous async-await