首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OperationContext在异步方法中为空。

OperationContext在异步方法中为空。
EN

Stack Overflow用户
提问于 2015-12-08 10:42:36
回答 2查看 1K关注 0票数 0

我有这样的服务:

代码语言:javascript
复制
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall)]
    public class CalculadoraService : ICalculadoraService
    {
        public int Add(int num1, int num2)
        {
            if(OperationContext.Current == null)
            {
                return -2;
            }
            else if(OperationContext.Current.SessionId == null)
            {
                return -1;
            }

            return num1 + num2;
        }



        public async Task<int> AddAsync(int num1, int num2)
        {
            return await Task<int>.Run(() =>
            {
                if (OperationContext.Current == null)
                {
                    return -2;
                }
                else if (OperationContext.Current.SessionId == null)
                {
                    return -1;
                }

                return num1 + num2;
            });
        }
    }

这是app配置文件:

代码语言:javascript
复制
<system.serviceModel>
    <services>
      <service name="WCFCalculadoraService.CalculadoraService">
        <!--El endpoint correspondiente al contrato de la calculadora. ¿Se puede tener más para otros contratos y aplicaciones?-->
        <!--<endpoint address="" binding="basicHttpBinding" contract="WCFCalculadoraService.ICalculadoraService">-->
        <endpoint address="" binding="netHttpBinding" contract="WCFCalculadoraService.ICalculadoraService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <!--Esto sirve para poder intercambiar información-->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/Design_Time_Addresses/WCFCalculadoraService/Service1/" />
          </baseAddresses>
        </host>
      </service>
    </services>


    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

这是我从客户端使用服务的代理:

代码语言:javascript
复制
public class WCFCalculadoraServiceProxy : ClientBase<ICalculadoraService>
    {
        public int Add(int num1, int num2)
        {
            //Lo que hace es llamar al método del servicio.
            return base.Channel.Add(num1, num2);
        }

        public async Task<int> AddAsync(int num1, int num2)
        {
            //Lo que hace es llamar al método del servicio.
            return await base.Channel.AddAsync(num1, num2);
        }
    }

当我调用Add方法时,结果是-1,因为OperationContext.SessionID是null。如果我调用AddAsync,则得到-2,因为OperationContext是空的。

我想知道在同步和异步方法这两种情况下如何获得SessionID,因为我希望将SessionID存储到静态变量中。

非常感谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-09 15:10:52

为了使OperationContext.Current.SessionOd不为null,您必须通过在接口定义上使用[ServiceContract(SessionMode=SessionMode.Required)]属性来配置服务接口以要求会话。

OperationContext.Current是线程本地的,这意味着它被绑定到由WCF创建的线程。它将不可用于Task.Run使用的线程池线程。但是在调用Task.Run之前很容易将会话id存储到变量中。

代码语言:javascript
复制
public async Task<int> AddAsync(int num1, int num2)
{
    var context = OperationContext.Current
    var sessionId = OperationContext.Current.SessionId;
    return await Task<int>.Run(() =>
    {
        if (context == null)
        {
            return -2;
        }
        else if (sessionId == null)
        {
            return -1;
        }

        return num1 + num2;
    });
}
票数 1
EN

Stack Overflow用户

发布于 2015-12-09 13:24:44

首先,不需要编写异步等价物,因为VS可以代替。您所需要做的就是添加服务引用->高级->允许生成异步操作

其次,如果OperationContext.Current.SessionId等于null,则表示不支持任何会话。您可能没有将SessionMode设置为“允许”或“必需”。

最后但并非最不重要的一点是,如果您没有自动生成客户端的代理类,那么可以从ClientBase或DuplexClientBase派生,然后也从T派生,以便正确定义方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34153762

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档