WCF客户端不调用异步方法

时间:2011-06-21 11:40:59

标签: wcf c#-4.0 asynchronous

我在WCF服务中实现了以下接口

[ServiceContract]
public interface IPrepaidService
{

    [OperationContract]
    PrepaidSubscriberInfo GetSubscriberInfo(string ctn);

    [OperationContractAttribute(AsyncPattern = true)]
    IAsyncResult BeginGetSubscriberInfo(string ctn, AsyncCallback cb, object state);
    PrepaidSubscriberInfo EndGetSubscriberInfo(IAsyncResult r);



}

这样

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class PrepaidService : IPrepaidService
{

        public PrepaidSubscriberInfo GetSubscriberInfo(string ctn)
        {

            PrepaidSubscriberInfo result = null;

            try
            {
        result = new PrepaidSubscriberInfo();
        ...

            }
            catch (Exception ex) { throw new Exception(ex.ToString(), ex); }
            return result;
        }

        public IAsyncResult BeginGetSubscriberInfo(string ctn, AsyncCallback cb, object state)
        {            
            Task<PrepaidSubscriberInfo> task = Task<PrepaidSubscriberInfo>.Factory.StartNew(_ => GetSubscriberInfo(ctn), state);
            if (cb != null) task.ContinueWith(res => cb(task));
            return task;
        }

        public PrepaidSubscriberInfo EndGetSubscriberInfo(IAsyncResult ar)
        {            
            return ((Task<PrepaidSubscriberInfo>)ar).Result;
        }
}

我生成了代理和配置文件:

  

c:\ temp&gt; svcutil http://localhost/Service.svc / async

  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="MetadataExchangeHttpBinding_IPrepaidService" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
            maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
            allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
              enabled="false" />
          <security mode="None">
            <transport clientCredentialType="Windows" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="Windows" negotiateServiceCredential="true" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost/Service.svc"
          binding="wsHttpBinding" bindingConfiguration="MetadataExchangeHttpBinding_IPrepaidService"
          contract="IPrepaidService" name="MetadataExchangeHttpBinding_IPrepaidService">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>

我正试图以这种方式在WCF客户端上调用异步方法

    static void Main(string[] args)
    {

        ChannelFactory<IPrepaidServiceChannel> factory = new ChannelFactory<IPrepaidServiceChannel>("MetadataExchangeHttpBinding_IPrepaidService");
        factory.Open();
        IPrepaidServiceChannel channelClient = factory.CreateChannel();

        IAsyncResult arAdd = channelClient.BeginGetSubscriberInfo("xxx", AddCallback, channelClient);

        IAsyncResult arAdd2 = channelClient.BeginGetSubscriberInfo("xxx", AddCallback, channelClient);

        IAsyncResult arAdd3 = channelClient.BeginGetSubscriberInfo("yyy", AddCallback, channelClient);

        IAsyncResult arAdd4 = channelClient.BeginGetSubscriberInfo("yyy", AddCallback, channelClient);
        Console.WriteLine("1");



        Console.ReadKey();

    }

    static void AddCallback(IAsyncResult ar)
    {
        var result = ((IPrepaidService)ar.AsyncState).EndGetSubscriberInfo(ar);
        Console.WriteLine("Result: {0}", result);
    }

但是WCF客户端始终在WCF服务上调用GetSubscriberInfo()方法而不是其异步版本 BeginGetSubscriberInfo和EndGetSubscriberInfo。当我删除[OperationContract] PrepaidSubscriberInfo GetSubscriberInfo(string ctn); 客户端调用异步版本。

对不起家伙的格式错误,但我无法使用此UI管理

1 个答案:

答案 0 :(得分:1)

客户端和服务可以独立执行/不执行异步。客户端调用async只是意味着从客户端的角度看,调用是异步的,服务甚至不必支持异步

该服务更喜欢同步异步,因此如果您希望调用异步服务,请从合同版本中删除同步版本