C# 与其他测试一起运行时,AsyncLocal测试失败
我正在尝试创建一个名为C# 与其他测试一起运行时,AsyncLocal测试失败,c#,.net,asynchronous,.net-core,scope,C#,.net,Asynchronous,.net Core,Scope,我正在尝试创建一个名为AuditScope的自定义范围类,通过该类可以通过AuditScope.current访问当前范围 如果存在嵌套范围,则当前范围是嵌套最多的范围 我希望这是线程安全的,因此我使用asynchlocal来确保当前作用域属于当前异步上下文,并且与其他请求没有冲突。这类似于TransactionScope类,如果您遇到过它的话 这是我的范围类: public sealed class AuditScope : IDisposable { private static r
AuditScope
的自定义范围类,通过该类可以通过AuditScope.current
访问当前范围
如果存在嵌套范围,则当前范围是嵌套最多的范围
我希望这是线程安全的,因此我使用asynchlocal
来确保当前作用域属于当前异步上下文,并且与其他请求没有冲突。这类似于TransactionScope
类,如果您遇到过它的话
这是我的范围类:
public sealed class AuditScope : IDisposable
{
private static readonly AsyncLocal<Stack<AuditScope>> ScopeStack = new();
public int ExecutedByUserId { get; }
public AuditScope(int executedByUserId)
{
ExecutedByUserId = executedByUserId;
if (ScopeStack.Value == null)
{
ScopeStack.Value = new Stack<AuditScope>();
}
ScopeStack.Value.Push(this);
}
public static AuditScope? Current
{
get
{
if (ScopeStack.Value == null || ScopeStack.Value.Count == 0)
{
return null;
}
return ScopeStack.Value.Peek();
}
}
public void Dispose()
{
ScopeStack.Value?.Pop();
}
}
当然,既然using
语句在不同的上下文中,这应该会起作用吗?为什么单独运行时通过,而与其他测试一起运行时不通过
关于完整性,请参阅下面我正在运行的其他测试,但我严重怀疑它们是否会直接影响它们:
[Test]
public void GivenNoCurrentScope_WhenCurrentScopeAccessed_ThenNull()
{
// Act
var result = AuditScope.Current;
// Arrange
Assert.Null(result);
}
[Test]
public void GivenScope_WhenScopeDisposed_ThenNull()
{
// Arrange
using (var scope = new AuditScope(1))
{
}
// Act
var result = AuditScope.Current;
// Arrange
Assert.Null(result);
}
[Test]
public void GivenScopeCreated_WhenCurrentScopeAccessed_ThenScopeReturned()
{
// Arrange
using (var scope = new AuditScope(1))
{
// Act
var result = AuditScope.Current;
// Arrange
Assert.NotNull(result);
Assert.AreEqual(scope, result);
}
}
[Test]
public void GivenNestedScopeCreated_WhenCurrentScopeAccessed_ThenNestedScopeReturned()
{
// Arrange
using (var scope = new AuditScope(1))
{
using (var nestedScope = new AuditScope(2))
{
// Act
var result = AuditScope.Current;
// Arrange
Assert.NotNull(result);
Assert.AreEqual(nestedScope, result);
}
}
}
[Test]
public void GivenNestedScopeCreated_WhenNestedScopeDisposed_ThenCurrentScopeRevertsToParent()
{
// Arrange
using (var scope = new AuditScope(1))
{
using (var nestedScope = new AuditScope(2))
{
}
// Act
var result = AuditScope.Current;
// Arrange
Assert.NotNull(result);
Assert.AreEqual(scope, result);
}
}
事实证明,在将
Stack
替换为ImmutableStack
时,一定存在引用问题
[Test]
public void GivenNoCurrentScope_WhenCurrentScopeAccessed_ThenNull()
{
// Act
var result = AuditScope.Current;
// Arrange
Assert.Null(result);
}
[Test]
public void GivenScope_WhenScopeDisposed_ThenNull()
{
// Arrange
using (var scope = new AuditScope(1))
{
}
// Act
var result = AuditScope.Current;
// Arrange
Assert.Null(result);
}
[Test]
public void GivenScopeCreated_WhenCurrentScopeAccessed_ThenScopeReturned()
{
// Arrange
using (var scope = new AuditScope(1))
{
// Act
var result = AuditScope.Current;
// Arrange
Assert.NotNull(result);
Assert.AreEqual(scope, result);
}
}
[Test]
public void GivenNestedScopeCreated_WhenCurrentScopeAccessed_ThenNestedScopeReturned()
{
// Arrange
using (var scope = new AuditScope(1))
{
using (var nestedScope = new AuditScope(2))
{
// Act
var result = AuditScope.Current;
// Arrange
Assert.NotNull(result);
Assert.AreEqual(nestedScope, result);
}
}
}
[Test]
public void GivenNestedScopeCreated_WhenNestedScopeDisposed_ThenCurrentScopeRevertsToParent()
{
// Arrange
using (var scope = new AuditScope(1))
{
using (var nestedScope = new AuditScope(2))
{
}
// Act
var result = AuditScope.Current;
// Arrange
Assert.NotNull(result);
Assert.AreEqual(scope, result);
}
}