Клиент WCF не вызывает асинхронные методы - PullRequest
0 голосов
/ 21 июня 2011

Я реализовал следующий интерфейс в моей службе 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> 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 всегда вызывает метод GetSubscriberInfo () в службе WCF вместо его асинхронной версии BeginGetSubscriberInfo и EndGetSubscriberInfo. Когда я удаляю [OperationContract] PrepaidSubscriberInfo GetSubscriberInfo (строка ctn); клиент вызывает асинхронную версию.

Извините, ребята, за плохое форматирование, но я не справился с этим пользовательским интерфейсом

1 Ответ

1 голос
/ 21 июня 2011

Клиент и служба могут выполнять / не выполнять асинхронную работу независимо.Клиент вызывает async просто означает, что с точки зрения клиента вызовы являются асинхронными, сервис не должен даже поддерживать async

Служба предпочтет синхронизацию по асинхронному, поэтому, если вы хотите, чтобы служба вызывалась асинхронно, удалитесинхронизировать версию с версией контракта

...