上周在pedramr blog上看到有人问是否能够异步调用Restful的WCF服务,下面便是具体实现异步调用Restful的WCF实现细节。通过本文的学习,有助于如下知识的掌握:
- 如何设定WCF的Restful支持
- 如何异步调用Restful的WCF服务
第一步:创建一个解决方案:AsyCallRestfulWcf,该解决方案包含下面四个项目:
项目名称
备注
AsyCallRestfulWcf.Contracts
WCF服务的契约项目,包含服务契约和数据契约的定义
AsyCallRestfulWcf.Service
WCF服务的具体实现
AsyCallRestfulWcf.Host
WCF服务的承载
AsyCallRestfulWcf.HttpClient
用Http 的方式异步调用WCF服务客户端
第二步:在项目AsyCallRestfulWcf.Contracts中创建服务契约IService.cs和数据契约Person.cs
Person.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Runtime.Serialization;
namespace AsyCallRestfulWcf.Contracts
{
[DataContract]
public class Person
{
[DataMember]
public string ID
{
get;
set;
}
[DataMember]
public string Name
{
get;
set;
}
[DataMember]
public int Age
{
get;
set;
}
}
}
IService.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
namespace AsyCallRestfulWcf.Contracts
{
[ServiceContract]
public interface IService
{
[OperationContract]
Person GetPerson(string id);
}
}
第三步:在项目AsyCallRestfulWcf.Service中创建服务实现类Service.cs
Service.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel.Web;
namespace AsyCallRestfulWcf.Service
{
public class Service:Contracts.IService
{
[WebInvoke(Method = "*", UriTemplate = "GetPerson?id={id}")]
public Contracts.Person GetPerson(string id)
{
System.Threading.Thread.Sleep(5000);
Contracts.Person p = new AsyCallRestfulWcf.Contracts.Person();
p.ID = id;
p.Name = "jillzhang";
p.Age = 25;
return p;
}
}
}
在服务方法中,用System.Threading.Thread.Sleep(5000);模拟一个比较耗时的操作
第四步 实现WCF服务的承载项目:AsyCallRestfulWcf.Host
添加一个应用程序配置文件app.config和代码文件Programe.cs
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="AsyCallRestfulWcf.Service.Service">
<host>
<baseAddresses>
<add baseAddress="http://locahost"/>
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" contract="AsyCallRestfulWcf.Contracts.IService"
behaviorConfiguration="RestfulBehavior" name="webHttpBinding">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="RestfulBehavior">
<webHttp/>
<synchronousReceive/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Programe.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
namespace AsyCallRestfulWcf.Host
{
public class Programe
{
protected static void Main()
{
using (ServiceHost host = new ServiceHost(typeof(Service.Service)))
{
host.Open();
Console.WriteLine("服务已经启动!");
Console.Read();
}
}
}
}
在App.config中,要使WCF支持Restful,要使用的binding是webHttpBinding
第五步:实现异步调用的客户端:AsyCallRestfulWcf.HttpClient
添加windows窗体Form1.
后台代码为:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace AsyCallRestfulWcf.HttpClient
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
System.Net.WebClient wc;
private void button1_Click(object sender, EventArgs e)
{
wc = new System.Net.WebClient();
wc.DownloadStringAsync(new Uri("http://localhost/GetPerson?id=1"));
wc.DownloadStringCompleted += new System.Net.DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
button1.Enabled = false;
button2.Enabled = true;
}
void wc_DownloadStringCompleted(object sender, System.Net.DownloadStringCompletedEventArgs e)
{
if (!e.Cancelled)
{
string content = e.Result;
richTextBox1.Text = content;
button1.Enabled = true;
button2.Enabled = false;
}
}
private void button2_Click(object sender, EventArgs e)
{
wc.CancelAsync();
button1.Enabled = true;
button2.Enabled = false;
richTextBox1.Text = "请求已经取消!";
}
}
}
现在就可以调试浏览了,将解决方案设置成多启动的、
然后F5,出现下面的界面
和
表明运行正常
点击开始调用,等待几秒后,下面的文本框便出现文字
在开始调用之后,点击取消调用可以取消请求
国际惯例,项目代码: