我们怎样才能创建一个CallContext中的异步.NET方法? [英] How can we create a callcontext for async .net methods?

查看:151
本文介绍了我们怎样才能创建一个CallContext中的异步.NET方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个同步的环境中,很容易创建一个作用域范围内它可以让你出带外上下文附加到当前线程。这方面的例子是当前的TransactionScope或线程静电记录上下文。

In a synchronous environment, it is easy to create a scoped context which allows you to attach out-of-band context to your current thread. Examples of this are the current TransactionScope or thread-static logging context.

using (new MyContext(5))
    Assert.Equal(5, MyContext.Current);

Assert.Equal(null, MyContext.Current);

有容易实现使用 IDisposable接口和线程静态字段的一个组合

It is easy to implement the context using a combination of IDisposable and a thread-static field.

显然,这种散开使用异步方法时,因为该上下文基于一个线程静电场。因此,此操作失败:

Obviously, this falls apart when using async methods, because the context is based on a thread-static field. So, this fails:

using (new MyContext(5))
{
    Assert.Equal(5, MyContext.Current);

    await DoSomethingAsync();

    Assert.Equal(5, MyContext.Current);
}

当然,我们也希望上下文被传递到调用链的异步方法,所以这应该工作,以及:

And of course we would also want that the context is passed to the async methods in the call chain, so this should work as well:

using (new MyContext(5))
{
    Assert.Equal(5, MyContext.Current);

    await AssertContextIs(5);
}

有没有人有一个想法如何实现这一点的?失去了带外环境中使用异步/计谋模式在做一些作品的code真难看。

Does anyone have an idea how this could be implemented? Losing out-of-band context when using the async/await pattern makes some pieces of the code really ugly.

想想异步的WebAPI电话,你想使用基于请求的情况下进行日志记录。您希望您的记录深藏在调用堆栈要知道请求ID,而不必需要一路过关斩将调用堆栈使用参数来传递请求ID。

Think of async WebAPI calls where you would like to use request-based context for logging purposes. You want your logger deep in the call stack to be aware of the request ID without having the need to pass that request ID all the way through the call stack using parameters.

感谢您的帮助!

推荐答案

最好的解决方案是使用 HttpContext.Current.Items 在ASP.NET或<$ C 。$ C> IOwinRequest [获取|设置] 在OWIN。是的,这确实意味着通过请求对象无处不在,这是有道理的,如果你觉得你的环境价值属于这一请求。如果你不舒服了库的方法寂寂OWIN,那么很容易写一个上下文包装对象,并通过周围吧。

The best solution is to use HttpContext.Current.Items in ASP.NET, or IOwinRequest.[Get|Set] in OWIN. Yes, this does mean passing the request object everywhere, which makes sense if you think of your "context value" as belonging to that request. If you're uncomfortable with a "library" method knowing about OWIN, then it's easy to write a "context wrapper" object and pass that around instead.

不过,如果你确信你不想身边经过任何东西,那么你就可以的使用 LogicalCallContext 万古不易的数据为我描述我的博客上。如果你只是关心日志记录,那么你会发现我的 AsyncDiagnostics库有用 - 它使用PostSharp注入方法名,你可以添加自己的信息进入异步栈以及

However, if you are sure you don't want to pass anything around, then you can use LogicalCallContext with immutable data as I describe on my blog. If you're just concerned about logging, then you may find my AsyncDiagnostics library useful - it uses PostSharp to inject method names, and you can add your own info into the "async stack" as well.

这篇关于我们怎样才能创建一个CallContext中的异步.NET方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆