WCF:异步调用长时间工作的服务
今天继续在讲解WCF方面的课程。关于长时间工作的服务,实现异步的方式有很多种,例如新开一个Thread去调用,或者采用添加引用后生成的Beginxxxx方法去做。本文介绍一种比较特殊的写法:直接通过回调委托实现。
1. 合约
using System.ServiceModel; namespace Contracts { [ServiceContract] public interface ILongworker { [OperationContract] //[OperationContract(IsOneWay=true)] //将该操作设置为IsOneWay,表示该操作不需要回复。客户端调用之后无需等待即可返回 //该模式下即便服务器端抛出异常也不会被客户端接收到。 void Dowork(); } }
2. 服务
using System; namespace Services { public class LongworkService:Contracts.ILongworker { #region ILongworker 成员 public void Dowork() { //这是一个长时间工作的服务方法 System.Threading.Thread.Sleep(10000);//设置休眠10秒钟 Console.WriteLine("服务器执行完了操作"); } #endregion } }
3. 宿主
using System; using System.ServiceModel; using System.ServiceModel.Description; namespace LongworkServiceHost { class Program { static void Main(string[] args) { #region 长时间工作的服务 using (ServiceHost host = new ServiceHost( typeof(Services.LongworkService), new Uri("http://localhost:8000/LongworkService") )) { host.AddServiceEndpoint( "Contracts.ILongworker", new BasicHttpBinding(), ""); ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); behavior.HttpGetEnabled = true; host.Description.Behaviors.Add(behavior); host.AddServiceEndpoint( "IMetadataExchange", MetadataExchangeBindings.CreateMexHttpBinding(), "mex"); host.Open(); Console.WriteLine("服务器已经准备好"); Console.Read(); } #endregion } } }
4. 客户端
Contracts.ILongworker proxy = new ChannelFactory<Contracts.ILongworker>( new BasicHttpBinding(), new EndpointAddress("http://localhost:8000/LongworkService")).CreateChannel(); Action action = new Action(() => { proxy.Dowork(); });//这一句必须这样写,而不能写成new Action(proxy.Dowork),那样实现不了异步效果 Console.WriteLine("异步调用之前的工作"); action.BeginInvoke((a) => { Console.WriteLine("调用结束"); }, null); Console.WriteLine("主程序继续其他的工作");