zoukankan      html  css  js  c++  java
  • Task-based Asynchronous Operation in WCF z

    Introduction

    Though performance blocking and sluggishness are the tailbacks for any application, we can easily overcome these bottlenecks by using asynchronous programming. But old-style practice for asynchronous programming is not way easy enough to write, debug and maintain. So what is the contemporary approach??

    Well, in my view, this is task based asynchronous programming, which is updated in .NET 4.5 through the use of keywords await and async. But what do async and await do? async and await are the way of controlling continuation. When a method uses the async keyword, it means it is an asynchronous method, which might have an await keyword inside, and if it has an await keyword, async will activate it. So, simply async activates the await, from which point, the asynchronous has been started. There is a nice explanation that has been given here.

    In WCF, we can also consider an asynchronous operation while the service operation creates a delaying call. There are three ways to implement asynchronous operations:

    • Task-based asynchronous
    • Event-based asynchronous
    • IAsyncResult asynchronous

    In this article, I am going to use task-based asynchronous operation since this is the most contemporary strategy.

    Okay. Let’s move to the code.

    Define and Implement Service

    A very simple Service contract such as:

    [ServiceContract]
    public interface IMessage
    {
        [OperationContract]
        Task<string> GetMessages(string msg);
    }
    

    With this simple contract, the implementation is just straight forward.

    public class MessageService : IMessage
    {
       async Task<string> IMessage.GetMessages(string msg)
       {
          var task = Task.Factory.StartNew(() =>
                                         {
                                             Thread.Sleep(10000);
                                             return "Return from Server : " + msg;
                                         });
         return await task.ConfigureAwait(false);
       }
    }
    

    Here, the method is marked with the async keyword, which means it might use await keyword inside. It also means that the method will be able to suspend and then resume asynchronously at await points. Moreover, it points the compiler to boost the outcome of the method or any exceptions that may happen into the return type.

    Service Hosting

    class Program
    {
        static void Main(string[] args)
        {
           var svcHost = new ServiceHost(typeof (MessageService));
           Console.WriteLine("Available Endpoints :
    ");
           svcHost.Description.Endpoints.ToList().ForEach
            (endpoints=> Console.WriteLine(endpoints.Address.ToString()));
           svcHost.Open();
           Console.ReadLine();
        }
    }
    

    Service Configuration

    <?xml version="1.0"?>
     <configuration>
         <system.serviceModel>
           <services>
              <service name="Rashim.RND.WCF.Asynchronous.ServiceImplementation.MessageService">
                 <host>
                     <baseAddresses>
                         <add baseAddress="net.Tcp://localhost:8732/"/>
                         <add baseAddress="http://localhost:8889/"/>
                     </baseAddresses>
                 </host>
                 <endpoint address="Tcp" binding="netTcpBinding" 
                 contract="Rashim.RND.WCF.Asynchronous.Services.IMessage"/>
                 <endpoint address="Http" binding="basicHttpBinding" 
                 contract="Rashim.RND.WCF.Asynchronous.Services.IMessage">
                     <identity>
                          <dns value="localhost"/>
                     </identity>
                 </endpoint>
                 <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
                 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
              </service>
           </services>
           <behaviors>
              <serviceBehaviors>
                 <behavior>
                     <serviceMetadata/>
                 </behavior>
              </serviceBehaviors>
           </behaviors>
         </system.serviceModel>
         <startup><supportedRuntime version="v4.0" 
         sku=".NETFramework,Version=v4.5"/></startup>
    </configuration>

    After configuring the service, we need to configure the client app to consume the service.

    Define Client

    A simple Console Application (Client):

    class Program
     {
        static void Main(string[] args)
        {
           GetResult();
           Console.ReadLine();
        }
    
        private async static void GetResult()
        {
           var client = new Proxy("BasicHttpBinding_IMessage");
           var task = Task.Factory.StartNew(() => client.GetMessages("Hello"));
           var str = await task;
           str.ContinueWith(e =>
           {
              if (e.IsCompleted)
               {
                  Console.WriteLine(str.Result);
               }
           });
          Console.WriteLine("Waiting for the result");
        }
     }

    Client Configuration

    <?xml version="1.0"?>
     <configuration>
       <system.serviceModel>
         <bindings>
           <basicHttpBinding>
             <binding name="BasicHttpBinding_IMessage" />
           </basicHttpBinding>
         </bindings>
         <client>
           <endpoint address="http://localhost:8889/Http" binding="basicHttpBinding"
              bindingConfiguration="BasicHttpBinding_IMessage" 
              contract="Rashim.RND.WCF.Asynchronous.Services.IMessage"
               name="BasicHttpBinding_IMessage" />
         </client>
       </system.serviceModel>
     </configuration>

    Finally, proxy class is given below through which the client will consume the services.

    public class Proxy : ClientBase<IMessage>, IMessage
     {
        public Proxy()
        {
        }
        public Proxy(string endpointConfigurationName) :
        base(endpointConfigurationName)
        {
        }
        public Task<string> GetMessages(string msg)
        {
          return Channel.GetMessages(msg);
        }
     }

    That’s it. Very easy stuff though.

  • 相关阅读:
    使用sequelize-auto生成sequelize的Models
    table中td内容过长自动换行
    编写一个方法,去掉数组的重复元素
    call, apply的用法意义以及区别是什么
    在javascript中使用媒体查询media query
    总结的一些封装好的javascript函数
    只对safari起作用的css hack
    javascrip实现无缝滚动
    Ensures there will be no 'console is undefined' errors
    jQuery.isEmptyObject()函数用于判断指定参数是否是一个空对象。
  • 原文地址:https://www.cnblogs.com/zeroone/p/4851953.html
Copyright © 2011-2022 走看看