gpt4 book ai didi

c# - 调用包含来自 MVC Controller 的异步调用的服务的正确模式

转载 作者:太空宇宙 更新时间:2023-11-03 12:45:41 27 4
gpt4 key购买 nike

我在 C# 中对 TAP 和 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 Controller 操作调用时,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
}

最佳答案

理想情况下,您应该避免 .Result.IsFaulted Task 的属性和 Task<T>对象,那是代码味道第一。当您使用这些对象时,您应该使用 asyncawait通过整个堆栈。请考虑以这种方式编写您的服务:

public async Task<OzCpAddOrUpdateEmailAddressToListOutput> 
AddOrUpdateEmailAddressToList(
OzCpAddOrUpdateEmailAddressToListInput aParams)
{
var result = new OzCpAddOrUpdateEmailAddressToListOutput();
try
{
var mailChimManager = new MailChimpManager(aParams.MailChimpApiKey);
Member mailChimpResult =
await mailChimManager.Members.AddOrUpdateAsync(
aParams.Listid,
new Member
{
EmailAddress = aParams.EmailAddress
});
}
catch (Exception ex)
{
result.ResultErrors.AddFatalError(PlatformErrors.UNKNOWN, ex.Message);
}
return result;
}

请注意,我能够删除所有不必要的属性轮询和检查。我们将该方法标记为 Task<OzCpAddOrUpdateEmailAddressToListOutput>返回并用 async 装饰它关键词。这允许我们使用 await方法体中的关键字。我们await .AddOrUpdateAsync这会产生 Member .

对服务的消费调用看起来很相似,遵循与 async 相同的范例和 await关键词 TaskTask<T>返回类型:

var mailChimpResult =
await _PlatformMailChimpService.AddOrUpdateEmailAddressToList(
new OzCpAddOrUpdateEmailAddressToListInput
{
EmailAddress = aFormCollection["aEmailAddress"],
Listid = ApplicationSettings.Newsletter.MailChimpListId.Value,
MailChimpApiKey = ApplicationSettings.Newsletter.MailChimpApiKey.Value
});

if (mailChimpResult.Result == true)
{
//So something
}

将“Async”一词添加到方法后缀被认为是最佳实践,以表示它是异步的,即; AddOrUpdateEmailAddressToListAsync .

关于c# - 调用包含来自 MVC Controller 的异步调用的服务的正确模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37403826/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com