Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 与其他测试一起运行时,AsyncLocal测试失败_C#_.net_Asynchronous_.net Core_Scope - Fatal编程技术网

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);
    }
}