【问题标题】:Why does _session.Use method not work properly?为什么 _session.Use 方法不能正常工作?
【发布时间】:2020-03-28 20:27:26
【问题描述】:

我有这样的工作:

[UnitOfWork]
public override void Execute(CompleteIRHJobArgs args)
{
    var robotUserId = _userRepo.GetAll().Where(p => p.UserName == TestaLIMSWPConsts.LIMSRobot).Select(p => p.Id).First();

    using (_session.Use(args.TenantId, robotUserId))
    {
        _instanceReciptHeaderDomainService.SetIRHToCompleteState(args.IRHIds);
    }
}

我找到robotUserId 并将其设置为当前用户。但是在我进入方法SetIRHToCompleteState 之后,_session.UserId.Valuenull。我认为这是错误的行为。我的 ABP 版本是 4.0.0。

public async Task SetIRHToCompleteState(List<int> irhIds)
{
    var irhs = await _instanceHeaderRepo.GetAll().Where(p => irhIds.Contains(p.Id)).ToListAsync();

    foreach (var t in irhs)
    {
        t.FlowState = FlowState.Completed;
        t.CompleteDate = Clock.Now;
        t.CompleteUserId = _session.UserId.Value;
    }
}

有时,

var irhs = await _instanceHeaderRepo.GetAll()...

抛出异常:

System.Transactions.TransactionInDoubtException:事务有问题。 ---> System.Data.SqlClient.SqlException:已经有一个打开的 DataReader 与此命令关联,必须先关闭。 ---> System.ComponentModel.Win32Exception: 等待操作超时

【问题讨论】:

    标签: asp.net async-await aspnetboilerplate sqlexception using-statement


    【解决方案1】:

    但是在进入方法SetIRHToCompleteState之后,_session.UserId.Value为空。

    SetIRHToCompleteStateasync 并在 using 范围被释放后继续运行。

    由于Execute 不是async,您不能使用await,但您可以调用AsyncHelper.RunSync

    // using Abp.Threading;
    
    using (_session.Use(args.TenantId, robotUserId))
    {
        AsyncHelper.RunSync(() => _instanceReciptHeaderDomainService.SetIRHToCompleteState(args.IRHIds));
    }
    

    这也可以避免“打开 DataReader”错误。


    来自aspnetboilerplate/aspnetboilerplate#1646

    它是在一个不在异步上下文中的后台线程中调用的。但这不是问题,因为后台作业管理器已经是单线程的,不会导致阻塞许多线程。
    Hangfire 实现也是如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-01
      • 1970-01-01
      • 2013-05-21
      • 2017-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多