使用 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
我目前有一个 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