首先,正如他们所说,我对异步操作充分了解是危险的。 Resharper给我一个警告,下面的代码我在ForEachAsync上有一个隐式捕获的“响应”对象的闭包。我理解为什么它会警告我,但我不确定我的实现是否存在任何特殊错误(顺便说一下,这确实有效),或者是否有更合适的方法来填充ForEachAsync中的“orders”集合。
public async Task<Response<IEnumerable<Order>>> HandleGetOrdersAsync(GetAllOrdersQuery query)
{
Expression<Func<Order, bool>> dateTimeFilter = order =>
order.OrderTime >= query.StartDateTime &&
order.OrderTime <= query.EndDateTime;
Expression<Func<order, bool>> isActiveFilter = order =>
!query.IsComplete ||
order.OrderStatus == OrderStatusName.Complete;
var items = _ctx.orders
.Include(c => c.Customers)
.Include(p => p.Payments)
.Where(dateTimeFilter)
.Where(isActiveFilter)
.OrderBy(n => n.OrderNo)
.Skip(query.PageSize * query.Page)
.Take(query.PageSize)
.Select(o => o);
// ... items count to be performed here ...
var response = new Response<IEnumerable<Order>>();
var orders = new List<Order>();
await items.ForEachAsync(i =>
{
var order = new Order
{
ResultNo = i.OrderNo,
CustomerName = i.Customer.Name,
PaymentType = i.Payment.Type
};
orders.Add(order);
}).ContinueWith(t =>
{
response = new Response<IEnumerable<Order>>(orders);
});
return response;
}
答案 0 :(得分:1)
您的代码将按照您已注意到的方式运行,但代理将保持orders
变量处于活动状态,因为它具有对它的引用,因此只要代理人,您的类就无法被GC收集没有资格进行垃圾收集。
var orders = new List<Order>();
await items.ForEachAsync(i =>
{
var order = new Order
{
ResultNo = i.OrderNo,
CustomerName = i.Customer.Name,
PaymentType = i.Payment.Type
};
orders.Add(order);
}).ContinueWith(t =>
{
response = new Response<IEnumerable<Order>>(orders);
});
如果orders
是值类型,例如int?
在这种情况下,它不适用,但如果orders
是一个整数且没有await
并且代码在捕获orders
变量的委托之后继续,那么在委托之后修改变量,并在稍后调用委托(想想事件处理程序)它将使用修改后的副本。为什么?因为事件虽然是整数,但是会捕获引用。
我想Resharper只是警告你,你需要决定它是否会引起你的问题。它所能做的就是警告你,因为在某些情况下它会引起问题,而在其他情况下它不会引起任何问题。