WCF REST HttpContext.Current Async / await

时间:2018-02-16 21:06:44

标签: c# asp.net wcf asynchronous async-await

我有一个使用在IIS中运行的WCF REST的ASP.NET应用程序。

我需要存储当前HTTP请求的变量,我使用HttpContext.Current.Items。我存储了我在global.asax中设置的一些请求ID,因此我可以在我的服务中更深入地使用它。我的服务正在进行一些I / O操作,所以我最近将它们从同步更改为异步。问题出在第一个await之后,HttpContext.Current变为空,因此我无法访问存储在HttpContext.Current.Items中的变量。

我的global.asax:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        HttpContext.Current.Items["CurrentRequestId"] = SetRequestId();
    }

我的WCF合同:

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class WcfService
{
    [OperationContract]
    [WebGet(UriTemplate = "Operation")]
    public async Task<bool> Operation()
    {
        var context = HttpContext.Current; // Current context available here

        await Task.Delay(1000).ConfigureAwait(true); // tried with both ConfigureAwait(true) and ConfigureAwait(false)

        context = HttpContext.Current; // Current context is always null here

        return true;
    }
}

我尝试在我的web.config文件中添加这些键,但它没有改变任何内容。

<appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
    <add key="wcf:disableOperationContextAsyncFlow" value="false"/>
</appSettings>

我正在使用.net 4.6.2

<httpRuntime targetFramework="4.6.2" />

在使用ASP.NET的WCF REST中等待异步方法之后是否可以保留HttpContext.Current?是否有HttpContext.Current.Items替代我可以用来实现我想做的事情?

编辑:这是一个简化的示例,但HttpContext.Current的使用方式更深,我宁愿不必在等待之前收集它并将其一直传递到每​​个单一方法。

2 个答案:

答案 0 :(得分:1)

这个问题实际上与异步代码无关;它与从(非请求)线程池线程中检索上下文变量有关。

链接博客中推荐的技术(包装HttpContext并将其提供给工作线程)非常危险。 HttpContext被设计为一次只能从一个线程访问,而AFAIK根本不是线程安全的。因此,在不同的线程之间分享它是一个受伤的世界。

所以我强烈建议您在异步方法之前从HttpContext中获取所需的所有内容,然后再使用它。

答案 1 :(得分:0)

我在WCF中遇到过类似的问题,在等待任务后我丢失了OperationContext。实际上在等待之后 - 从线程池分配的线程没有上下文(基本上是一个不同的线程)。我们创建了一个通用的包装器方法来处理这个问题。下面我尝试在你的问题的上下文中转换相同的。试试吧:

.btn.active {
  background-color: limegreen;
}

大卫关于线程安全的观点 - 我考虑过它并做了一些尽职调查以确保线程安全。