【发布时间】:2015-10-02 14:43:07
【问题描述】:
我使用 ASP.NET MVC WebAPI 编写 Web 应用程序,我想将当前的同步代码转换为异步代码以进行优化。问题是我用从存储库中获取的多个对象填充 ViewModel。这些来自存储库的调用应该是异步的。
假设我有关于此接口的存储库调用的签名
public interface ICompanyRepository
{
IEnumerable<Company> GetCompanies();
IEnumerable<Address> GetAddresses();
}
ViewModel 定义
public class CompaniesFullViewModel
{
public IEnumerable<Company> Companies { get; set; }
public IEnumerable<Address> Addresses { get; set; }
}
和控制器:
public class CompanyController
{
public readonly ICompanyRepository Repository { get; private set; }
public CompanyController(IRepository repository)
{
Repository = repository;
}
[ResponseType(typeof(CompaniesFullViewModel))]
public HttpResponseMessage Get()
{
var companies = Repository.GetCompanies();
var addresses = Repository.GetAddresses();
HttpStatusCode statusCode = companies.Any()
? HttpStatusCode.OK
: HttpStatusCode.PartialContent;
return
Request.CreateResponse(
statusCode,
new CompaniesFullViewModel
{
Companies = companies,
Addresses = addresses
});
}
}
此外,我已经对控制器进行了测试:
[TestClass]
public sealed class CompanyTestController : BaseTestController
{
#region Fields
private static Mock<ICompanyRepository> _repositoryMock;
private static CompanyController _controller;
#endregion
[ClassInitialize]
public static void Initialize(TestContext testContext)
{
// Mock repository
_repositoryMock = new Mock<ICompanyRepository>();
DependencyResolver.Default.Container.RegisterInstance(_repositoryMock.Object);
// Create controller
_controller =
DependencyResolver.Default.Container.Resolve<CompanyController>();
// Init request
_controller.Request = new HttpRequestMessage();
_controller.Request.SetConfiguration(new HttpConfiguration());
}
[ClassCleanup]
public static void Cleanup()
{
_controller.Dispose();
}
[TestMethod]
public void Get_ActionExecutes_ReturnsEmptyCompaniesViewModel()
{
var companies = new List<Company>();
var addresses = new List<Address>();
// Setup fake method
_repositoryMock
.Setup(c => c.GetCompanies())
.Returns(companies);
_repositoryMock
.Setup(c => c.GetAddresses())
.Returns(addresses);
// Execute action
var response = _controller.Get();
// Check the response
Assert.AreEqual(HttpStatusCode.PartialContent, response.StatusCode);
}
}
如果存储库是异步的并且签名如下所示,我如何将控制器转换为异步:
public interface ICompanyRepository
{
Task<IEnumerable<Company>> GetCompaniesAsync();
Task<IEnumerable<Address>> GetAddressesAsync();
}
【问题讨论】:
-
也许我错过了什么。控制器签名不只是更改为
public async Task<HttpResponseMessage> Get()。那么您只需await您现在的异步存储库调用? -
@Andree:
I want to transform current synchronous code to asynchronous for optimization你确定那会做你想做的事吗?请记住,“异步”!=“更快”。 -
@StephenCleary 我知道这并不一定意味着更快,但我希望服务器负载高,部分长时间运行的查询,所以我决定运行我自己的基准来比较同步与. 异步解决方案。
标签: c# asp.net asp.net-mvc asp.net-web-api moq