为什么 _session.Use 方法不能正常工作?
Why does _session.Use method not work properly?
我有一份这样的工作:
[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.Value
是 null
。我认为这是错误的行为。我的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: The transaction is in doubt. ---> System.Data.SqlClient.SqlException: There is already an open DataReader associated with this Command which must be closed first. ---> System.ComponentModel.Win32Exception: The wait operation timed out
But after step into method SetIRHToCompleteState
, _session.UserId.Value
is null.
SetIRHToCompleteState
是 async
并在处理 using
作用域后继续 运行。
因为 Execute
不是 async
,你不能 await
但你可以调用 AsyncHelper.RunSync
。
// using Abp.Threading;
using (_session.Use(args.TenantId, robotUserId))
{
AsyncHelper.RunSync(() => _instanceReciptHeaderDomainService.SetIRHToCompleteState(args.IRHIds));
}
这也可以避免 "open DataReader" 错误。
来自 aspnetboilerplate/aspnetboilerplate#1646:
it's called in a background thread which is not inside an async context. But it's not a problem since background job manager is already single threaded and does not cause to block many threads.
Hangfire implementation is also like that.
我有一份这样的工作:
[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.Value
是 null
。我认为这是错误的行为。我的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: The transaction is in doubt. ---> System.Data.SqlClient.SqlException: There is already an open DataReader associated with this Command which must be closed first. ---> System.ComponentModel.Win32Exception: The wait operation timed out
But after step into method
SetIRHToCompleteState
,_session.UserId.Value
is null.
SetIRHToCompleteState
是 async
并在处理 using
作用域后继续 运行。
因为 Execute
不是 async
,你不能 await
但你可以调用 AsyncHelper.RunSync
。
// using Abp.Threading;
using (_session.Use(args.TenantId, robotUserId))
{
AsyncHelper.RunSync(() => _instanceReciptHeaderDomainService.SetIRHToCompleteState(args.IRHIds));
}
这也可以避免 "open DataReader" 错误。
来自 aspnetboilerplate/aspnetboilerplate#1646:
it's called in a background thread which is not inside an async context. But it's not a problem since background job manager is already single threaded and does not cause to block many threads.
Hangfire implementation is also like that.