我们的在线商店有一个ASP.Net MVC应用程序。用户必须从多种付款方式中进行选择才能购买。为此,我们实现了一个抽象工厂模式:
public interface IPaymentServiceFactory
{
IPaymentService GetPaymentService(PaymentServiceEnum paymentServiceType);
}
public interface IPaymentService
{
PaymentSettingsModel GetPaymentSettingsModel();
}
它用于我们的行动:
public ActionResult ProcessCart(PaymentDataModel paymentData)
{
var paymentService = _paymentServiceFactory.GetPaymentService(paymentData.PaymentServiceType);
var paymentSettings = paymentService.GetPaymentSettingsModel();
}
当我们了解某些付款方式需要内部异步调用时,就会出现问题。例如,必须通过http异步调用第三方在线支付服务方法来创建支付对象。实施:
public class OnlinePaymentService : IPaymentService
{
private readonly IOnlinePaymentServiceApiClient _client;
public async Task<PaymentSettingsModel> GetPaymentSettings()
{
var result = await _client.CreatePaymentAsync();
return result;
}
}
因此我们提出了一个问题:如何处理不同付款方式的异步和同步方案。我们决定让一切都异步。更新的代码:
public interface IPaymentService
{
Task<PaymentSettingsModel> GetPaymentSettings();
}
public async Task<ActionResult> ProcessCart(PaymentDataModel paymentData)
{
var paymentService = _paymentServiceFactory.GetPaymentService(paymentData.PaymentServiceType);
var paymentSettings = await paymentService.GetPaymentSettingsModel();
}
到目前为止一切顺利,但为了实现所有其他付款方式,我们被迫使用Task.Run:
public class CashPaymentService : IPaymentService
{
public async Task<PaymentSettingsModel> GetPaymentSettings()
{
return await Task.Run(() => new PaymentSettingsModel());;
}
}
据我所知,这会创建两个不同的线程来处理Action,这可能导致performance issue。 有办法避免这种后果吗?在特定情况下使用Task.Run真的很糟糕吗?
答案 0 :(得分:3)
在特定情况下使用Task.Run真的很糟糕吗?
是的,主要是因为它不必要地使事情变得复杂。
您可以使用Task.FromResult
返回已完成的任务,其结果为给定值。
这是完全同步的:
public class CashPaymentService : IPaymentService
{
public Task<PaymentSettingsModel> GetPaymentSettings()
{
return Task.FromResult( new PaymentSettingsModel() );
}
}
请注意,此处缺少async
- 这是可能的,因为它是一个实现细节,而不是IPaymentService
定义的一部分。