zoukankan      html  css  js  c++  java
  • WCF异步调用

    WCF异步调用:

    WCF可以通过使用下列三种方法之一实现异步操作:

    1、基于任务的异步模式:(使用Task实现)
    基于任务的异步模式是实现异步操作的首选方法,因为它最简单且最直接。

    2、基于事件的异步模式:(工具 (Svcutil.exe) 需要同时指定 /async 和 /tcv:Version35 命令选项)
    基于事件的异步模型仅在 .NET Framework 版本 3.5 中可用。

    3、IAsyncResult 异步模式:(工具 (Svcutil.exe) 需要指定 /async 命令选项)

    本文以 IAsyncResult 异步模式 为例,在VS2013环境下测试通过。

    示例代码一: 基本WCF异步方法

    服务端:

    [ServiceContract]
    public interface ICalculate
    {
    [OperationContract]
    int Add(int a, int b);

    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginAdd(int a, int b, AsyncCallback callBack, object state);

    int EndAdd(IAsyncResult ar);
    }

    public class CalculateService : ICalculate
    {
    public int Add(int a, int b)
    {
    Console.WriteLine("服务器方法 Add 开始执行: {0}", DateTime.Now);
    try
    {
    Thread.Sleep(5000);
    return a + b;
    }
    finally
    {
    Console.WriteLine("服务器方法 Add 执行完成: {0}", DateTime.Now);
    }
    }
    public IAsyncResult BeginAdd(int a, int b, AsyncCallback callBack, object state)
    {
    throw new Exception("The method or operation is not implemented.");
    }

    public int EndAdd(IAsyncResult ar)
    {
    throw new Exception("The method or operation is not implemented.");
    }
    }

    WCF配置文件:

    <service name="WcfService2.CalculateService">
    <endpoint address="" binding="netTcpBinding" contract="WcfService2.ICalculate"/>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
    <baseAddresses>
    <add baseAddress="http://localhost:8733/Design_Time_Addresses/WcfService2/CalculateService/" />
    <add baseAddress="net.tcp://localhost:8734/Design_Time_Addresses/WcfService2/CalculateService/" />
    </baseAddresses>
    </host>
    </service>

    客户端:

    引用服务:在引用服务时,左下角点击“高级”按钮,勾选“生成异步操作”即可。

    CalculateClient client = new CalculateClient();
    //int result = client.Add(5, 7); // 同步方法
    client.AddCompleted += client_AddCompleted;
    client.AddAsync(3, 2); // 异步方法

    private void client_AddCompleted(object sender, AddCompletedEventArgs e)
    {
    try
    {
    int result = e.Result;

    CalculateClient client = (CalculateClient)sender;
    if (client != null)
    {
    // 释放资源。
    client.Close();
    }
    }
    catch (Exception ex)
    {
    Console.WriteLine(ex.Message);
    }
    }

    示例代码二: WCF异步返回其它类型数据,例如数组。

    [ServiceContract]
    public interface IService3
    {
    [OperationContractAttribute]
    List<string> SampleMethod(int num);

    [OperationContractAttribute(AsyncPattern = true)]
    IAsyncResult BeginSampleMethod(int num, AsyncCallback callback, object asyncState);

    //Note: There is no OperationContractAttribute for the end method.
    List<string> EndSampleMethod(IAsyncResult result);
    }


    public class Service3 : IService3
    {
    public List<string> SampleMethod(int num)
    {
    List<string> list = new List<string>();
    list.Add("aaa");
    list.Add("bbb");

    //Log.GetInstance().LogInfo(LogLevel.Message, "SampleMethod", "num: "+num.ToString());
    return list;
    }

    public IAsyncResult BeginSampleMethod(int num, AsyncCallback callback, object asyncState)
    {
    // 经过测试,异步调用时,该方法未执行。
    //Console.WriteLine("BeginSampleMethod called with: " + msg);
    //return new CompletedAsyncResult<List<string>>();

    //Log.GetInstance().LogInfo(LogLevel.Message, "BeginSampleMethod", "num: " + num.ToString());

    throw new Exception("The method or operation is not implemented.");
    }

    public List<string> EndSampleMethod(IAsyncResult r)
    {
    // 经过测试,异步调用时,该方法未执行。
    //CompletedAsyncResult<List<string>> result = r as CompletedAsyncResult<List<string>>;
    //Console.WriteLine("EndSampleMethod called with: " + result.Data);
    //return result.Data;

    //Log.GetInstance().LogInfo(LogLevel.Message, "EndSampleMethod", "not.");

    throw new Exception("The method or operation is not implemented.");
    }
    }

    测试代码:

    // 示例1:
    //CalculateClient client = new CalculateClient();
    ////int result = client.Add(5, 7); // 同步方法
    //client.AddCompleted += client_AddCompleted;
    //client.AddAsync(3, 2); // 异步方法

    // 示例2:
    Service3Client client3 = new Service3Client();
    string[] list = client3.SampleMethod(3); // 同步方法
    client3.SampleMethodCompleted += client3_SampleMethodCompleted;
    client3.SampleMethodAsync(3);// 异步方法

    private void client3_SampleMethodCompleted(object sender, SampleMethodCompletedEventArgs e)
    {
    try
    {
    string[] message = e.Result;

    Service3Client client = (Service3Client)sender;
    if (client != null)
    {
    // 释放资源。
    client.Close();
    }
    }
    catch (Exception ex)
    {
    Console.WriteLine(ex.Message);
    }
    }

    示例代码三: WCF异步返回其它类型数据,并带有 ref 和 out 参数

    [ServiceContract]
    public interface IService3
    {
    [OperationContractAttribute]
    List<string> SampleMethod(int num, ref string inout, out string outonly);

    [OperationContractAttribute(AsyncPattern = true)]
    IAsyncResult BeginSampleMethod(int num, ref string inout, AsyncCallback callback, object asyncState);

    //Note: There is no OperationContractAttribute for the end method.
    List<string> EndSampleMethod(ref string inout, out string outonly, IAsyncResult result);
    }


    public class Service3 : IService3
    {
    public List<string> SampleMethod(int num, ref string inout, out string outonly)
    {
    List<string> list = new List<string>();
    list.Add("aaa");
    list.Add("bbb");

    inout += " is ok.";
    outonly = "this is " + inout;

    //Log.GetInstance().LogInfo(LogLevel.Message, "SampleMethod", "num: "+num.ToString());
    return list;
    }

    public IAsyncResult BeginSampleMethod(int num, ref string inout, AsyncCallback callback, object asyncState)
    {
    // 经过测试,异步调用时,该方法未执行。
    //Console.WriteLine("BeginSampleMethod called with: " + msg);
    //return new CompletedAsyncResult<List<string>>();

    //Log.GetInstance().LogInfo(LogLevel.Message, "BeginSampleMethod", "num: " + num.ToString());

    throw new Exception("The method or operation is not implemented.");
    }

    public List<string> EndSampleMethod(ref string inout, out string outonly, IAsyncResult result)
    {
    // 经过测试,异步调用时,该方法未执行。
    //CompletedAsyncResult<List<string>> result = r as CompletedAsyncResult<List<string>>;
    //Console.WriteLine("EndSampleMethod called with: " + result.Data);
    //return result.Data;

    //Log.GetInstance().LogInfo(LogLevel.Message, "EndSampleMethod", "not.");

    throw new Exception("The method or operation is not implemented.");
    }
    }

    调用方法:

    // 示例3:
    Service3Client client3 = new Service3Client();
    string inout = "hello";
    string outonly = string.Empty;
    //string[] list = client3.SampleMethod(3, ref inout, out outonly); // 同步方法
    client3.SampleMethodCompleted += client3_SampleMethodCompleted;
    client3.SampleMethodAsync(3, inout, outonly);// 异步方法

    private void client3_SampleMethodCompleted(object sender, SampleMethodCompletedEventArgs e)
    {
    try
    {
    string[] message = e.Result; // 返回值

    string inout = e.inout; // ref 参数
    string outonly = e.outonly; // out 参数

    Service3Client client = (Service3Client)sender;
    if (client != null)
    {
    // 释放资源。
    client.Close();
    }
    }
    catch (Exception ex)
    {
    Console.WriteLine(ex.Message);
    }
    }

    说明:以上内容来源于网络与MSDN。

  • 相关阅读:
    【HeadFirst设计模式学习笔记】10 组合模式
    【HeadFirst 设计模式学习笔记】12 代理模式
    【HeadFirst 设计模式学习笔记】15 享元模式拾零
    【HeadFirst 设计模式学习笔记】16 建筑者(Builder)模式拾零
    【HeadFirst 设计模式学习笔记】11 状态模式
    搜索引擎设计实用教程(1)以百度为例 之一:查询处理以及分词技术
    最容易写错的100个字
    看完这个我流泪了,人生有太多的误会和无奈……
    哈佛成功金言
    上海的朋友注意了,周六气温可能骤降到1℃
  • 原文地址:https://www.cnblogs.com/dblg/p/5010133.html
Copyright © 2011-2022 走看看