异步方法

时间:2015-12-08 10:42:37

标签: c# wcf async-await

我有这项服务:

[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;
            });
        }
    }

这是应用程序配置文件:

<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>

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

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为null。

我想知道如何在两种情况下获得SessionID,sync和async方法,因为我想将SessionID存储到静态变量中。

非常感谢。

2 个答案:

答案 0 :(得分:0)

首先,不需要编写异步等价物,因为VS可以代替它。您需要做的就是添加服务参考 - &gt;高级 - &gt;允许生成异步操作

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

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

答案 1 :(得分:0)

如果OperationContext.Current.SessionOd不为null,则必须使用接口定义上的[ServiceContract(SessionMode=SessionMode.Required)]属性将服务接口配置为要求会话。

OperationContext.Current是本地线程,这意味着它绑定到WCF创建的线程。它不可用于Task.Run使用的线程池线程。但是在调用Task.Run

之前,很容易将会话ID存储到变量中
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;
    });
}