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。

posted on 2015-12-01 15:06  晴空  阅读(562)  评论(0编辑  收藏  举报

导航