使用 CallContext 存储 WCF 的 HttpContext

Using the CallContext to store the HttpContext for WCF

我目前有一个 WCF 服务,用于执行一些数据库查询和发送邮件。长话短说,这两种方法都是异步的,在它们的实现中的某个地方使用 HttpContext.Current

我最初的问题是,在第一个 await 之后,HttpContext.Current 变为 null,因此,第二个操作失败。我现在在 Google 上搜索了几个小时,我测试了我发现的所有内容......自定义同步上下文,web.config 中的 appSettings,针对 .NET 4.5,启用 ASP.NET 兼容性,但没有成功了。

然后,我发现this SO post在谈论CallContext。基本上,想法是将 HttpContext.Current 存储在 CallContext 中。我测试了,yeepee,它起作用了。但是,由于我不知道 CallContext 到底是什么,所以我阅读了它。

我不确定我是否真的理解正确,但在阅读之后,我有一个顾虑。我可能是错的,但似乎不能保证异步调用完成后恢复的线程与初始线程相同。问题是我在 HttpContext 中存储了几个值,我担心第一个方法使用用户 A 值执行,然后,一旦异步调用完成,第二个方法使用用户 B 值执行(因为 HttpContext 不一样)。

我想人们会很想告诉我只将这些值存储在 CallContext 中,但我在遇到 WCF 问题之前创建了一个完整的体系结构,所以我不想完全审查它,这就是为什么 CallContext 会派上用场,因为更改很小。

谁能告诉我我的理论是否正确?

您应该更改您的服务,以使它们不依赖于 HttpContext.Current。最好完全不依赖 HttpContext

HttpContext.Current 是 UI 线程的服务器端等效项。只是不要在不需要依赖它的代码上使用它。

WCF 是开箱即用的完整 SOA 架构,支持多种协议,一切都是可配置的,此外您还可以扩展自定义一切。所以获得一切是非常tricky.Just基础知识:

三种类型的 WCF 并发性 是:

Single: 在给定的时刻,单个请求可以访问 WCF 服务对象。

Multiple:在这种情况下,WCF 服务对象可以在任何给定时刻处理多个请求。

Reentrant: 单个请求线程可以访问WCF服务对象,但是线程可以退出WCF服务调用另一个WCF服务或者也可以通过调用WCF客户端回调并重新进入无死锁。

看起来很简单但是等等它有 实例化 模式 不同于 并发

- 每次调用 为每个客户端请求创建一个新的 InstanceContext(以及服务对象)。

- 每个会话 为每个新的客户端会话创建一个新的 InstanceContext(以及服务对象)并在该会话的生命周期内维护(这需要支持会话的绑定).

- 单个实例:单个 InstanceContext(以及服务对象)在应用程序的生命周期内处理所有客户端请求。

默认实例模式为每会话,默认并发模式为单一

这意味着对于 WCF 服务,直到您更改您的服务只有一个实例上下文,一次最多允许一个线程在实例上下文中处理消息。希望使用相同实例上下文的其他线程必须阻塞,直到原始线程退出实例上下文

因此,除非您为此更改了代码并希望它发生,否则您担心的事情似乎不可能发生。

更多详情请参考:MSDN