У нас есть приложение 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, что может вызвать проблему производительности .
Есть ли способ избежать таких последствий? Неужели так плохо использовать Task.Run в конкретном случае?