linq 我可以在C#中异步调用datacontext类吗?

nkoocmlb  于 2022-12-06  发布在  C#
关注(0)|答案(2)|浏览(137)

这里我尝试从我的方法中异步调用DbContext对象。这会对性能产生影响吗?我知道实体框架不是线程安全的。

private async Task HasPreviousRecords(long passengerid, long segmentid, short legnumber, long inventoryLegid, string unitdesignator)
{
    var defaultTime = Convert.ToDateTime("9999-12-31 00:00:00.000");
    var records = _baseContext.PassengerJourneyLegVersions.Select(s => s).Where(s =>
                         s.VersionEndUTC != defaultTime &&
                         s.LiftStatus.Equals(1) &&
                         s.UnitDesignator != string.Empty &&
                         s.InventoryLegID.Equals(inventoryLegid) &&
                         s.LegNumber.Equals(legnumber) &&
                         s.SegmentID.Equals(segmentid) &&
                         s.PassengerID.Equals(passengerid)).ToList().OrderByDescending(s => s.VersionStartUTC).FirstOrDefault();

    if (records != null)
    {
        if (unitdesignator != records.UnitDesignator)
        {
            var passengerJourneryLeg = new PassengerJourneryLeg()
                    {
                        InventoryLegid = Convert.ToInt32(inventoryLegid),
                        Legnumber = Convert.ToInt32(legnumber),
                        Passengerid = Convert.ToInt32(passengerid),
                        Segmentid = Convert.ToInt32(segmentid)
                    };
            await PushMessageToQueue(passengerJourneryLeg);
        }
    }
}

内容类别具有相依性的单一存留期。

xesrikrc

xesrikrc1#

一个常见的误解是异步操作会比同步操作执行得“更快”,或者延迟更短。这是不正确的。由于异步状态机的创建和排队延续的成本,异步调用通常会引入少量(有时是不可测量的)额外延迟。
也就是说,您从应用程序中的异步I/O中获得的是 * 吞吐量 * 的显著提高。通过不使用阻塞I/O调用来束缚线程,这些线程现在可以自由地执行更多的工作,从而为您的应用程序带来更大的吞吐量。
Entity Framework Core提供了必须等待的常见延迟执行方法的异步变体(ToListAsync vs ToListFirstOrDefaultAsync vs FirstOrDefault),并且在切换到异步时应该使用。
此外,当查询上下文时,如果只需要一条记录,您希望避免将整个集合投影到内存中。以下代码段添加了几个优化:

  • 它从同步切换到异步
  • 它删除了不必要的。选择调用
  • 它停止在内存中投影整个集合,而是在数据库端执行select top 1查询
private async Task HasPreviousRecords(long passengerid, long segmentid, short legnumber, long inventoryLegid, string unitdesignator)
{
    var defaultTime = Convert.ToDateTime("9999-12-31 00:00:00.000");
    var records = await _baseContext.PassengerJourneyLegVersions
        .Where(s =>
                 s.VersionEndUTC != defaultTime &&
                 s.LiftStatus.Equals(1) &&
                 s.UnitDesignator != string.Empty &&
                 s.InventoryLegID.Equals(inventoryLegid) &&
                 s.LegNumber.Equals(legnumber) &&
                 s.SegmentID.Equals(segmentid) &&
                 s.PassengerID.Equals(passengerid))
        .OrderByDescending(s => s.VersionStartUTC)
        .FirstOrDefaultAsync();
    
    if (records != null)
    {
        if (unitdesignator != records.UnitDesignator)
        {
            var passengerJourneryLeg = new PassengerJourneryLeg()
            {
                InventoryLegid = Convert.ToInt32(inventoryLegid),
                Legnumber = Convert.ToInt32(legnumber),
                Passengerid = Convert.ToInt32(passengerid),
                Segmentid = Convert.ToInt32(segmentid)
            };
            await PushMessageToQueue(passengerJourneryLeg);
        }
    }
}

请注意,DbContext绝对不应该是单一对象。它应该是Scoped或Transient,而且应该在每次使用内容结束时处置。

lyr7nygr

lyr7nygr2#

在异步方法中使用EF上下文是可以的,但是您需要确保任何可能并行运行的方法都没有使用相同的上下文。

相关问题