我有一个UserScope类,其功能类似于TransactionScope,即它将当前状态存储在本地线程中。当然,此方法在对await的调用中不起作用,在.NET 4.5.1中添加TransactionScope之前,TransactionScopeAsyncFlowOption也无效。

我可以使用哪种替代线程本地的方法,以便UserScope在单线程和多线程方案中可以相同地使用? (如果安装了4.5.1,我将进行反编译以查看TransactionScope的工作方式。)这是我所拥有内容的简化版本:

class User {
    readonly string name;

    public User(string name) {
        this.name = name;
    }

    public string Name {
        get { return this.name; }
    }
}

class UserScope : IDisposable {
    readonly User user;

    [ThreadStatic]
    static UserScope currentScope;

    public UserScope(User user) {
        this.user = user;
        currentScope = this;
    }

    public static User User {
        get { return currentScope != null ? currentScope.user : null; }
    }

    public void Dispose() {
        ///...
    }
}

这是我期望可以进行的测试:

static async Task Test() {
    var user = new User("Thread Flintstone");
    using (new UserScope(user)) {
        await Task.Run(delegate {
            Console.WriteLine("Crashing with NRE...");
            Console.WriteLine("The current user is: {0}", UserScope.User.Name);
        });
    }
}

static void Main(string[] args) {
    Test().Wait();
    Console.ReadLine();
}

最佳答案

在.NET 4.5完整框架中,您可以为此使用逻辑调用上下文:

static async Task Test()
{
    CallContext.LogicalSetData("Name", "Thread Flintstone");
    await Task.Run(delegate
    {
        //Console.WriteLine("Crashing with NRE...");
        Console.WriteLine("The current user is: {0}", CallContext.LogicalGetData("Name"));
    });
}

static void Main(string[] args)
{
    Test().Wait();
    Console.ReadLine();
}

但是,您应该只将不可变数据存储在逻辑调用上下文中。我有more details on my blog。我一直想将其包装到AsyncLocal<T>库中,但是(尚未)找到时间。

关于c# - 跨范围共享范围,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22363830/

10-13 03:41