c# – 在[IsOneWay = true] WCF服务异步和使用客户端上的任务调
如果我有一个定义的服务:
[ServiceContract(SessionMode = SessionMode.NotAllowed)] public interface IMyService { [OperationContract(IsOneWay = true)] [ReceiveContextEnabled(ManualControl = true)] void DoSomething(Message<XElement> message); } 我想从我的客户端异步调用它(使用不从svcutil生成的共享契约或添加服务引用)我可以这样做: Task task = Task.Factory.StartNew(() => myService.DoSomething(message)); ... some other code task.Wait(); 我还可以将我的服务定义为异步: [ServiceContract(SessionMode = SessionMode.NotAllowed)] public interface ICacheKeyExchangeAsync { [OperationContract(IsOneWay = true,AsyncPattern = true)] [ReceiveContextEnabled(ManualControl = true)] IAsyncResult BeginDoSomething(Message<XElement> message,AsyncCallback callback,object state); void EndDoSomething(IAsyncResult result); } 而是这样做 IAsyncResult result = myService.BeginDoSomething(message,null,null); .... some other code myService.EndDoSomething(result); 这些方法之间是否存在显着差异? 解决方法
是的,Thread Pool线程利用率存在差异.
CLR线程池分为两种类型的线程:worker和I / O(有关它们的更多信息,可以在Simple description of worker and I/O threads in .NET和MSDN找到).一般来说,线程池为每个核心提供250个工作线程和1000个I / O线程,因此您可以使用工作线程处理您的WCF服务输入,并使用I / O线程等待异步发送/接收操作完成(这是支持的)在Windows操作系统级别上overlapped I/O机制). 记住这一点,让我们看一下使用ThreadPool.GetAvailableThreads()方法将两种方法用于哪些线程: int worker; int ioCompletion; ThreadPool.GetAvailableThreads(out worker,out ioCompletion); Console.WriteLine("{0} worker and {1} I/O threads are available",worker,ioCompletion); 我将仅显示客户端的线程池利用率的结果,但对于服务器端也是如此. 用于单向WCF操作的APM方法. 对于WCF合同: [ServiceContract] public interface IService1 { [OperationContract(IsOneWay = true,AsyncPattern = true)] IAsyncResult BeginDoSomething(int value,object state); void EndDoSomething(IAsyncResult result); } 让我们使用下一个代码从客户端向服务器发送100个请求: ChannelFactory<IService1> channelFactory = new ChannelFactory<IService1>(); var client = channelFactory.CreateChannel(); for (int i = 0; i < 100; i++) { int worker; int ioCompletion; ThreadPool.GetAvailableThreads(out worker,out ioCompletion); Console.WriteLine("{0} worker and {1} I/O threads are available",ioCompletion); client.BeginDoSomething(i,asyncCallback,null); } 输出是: 1023 worker and 1000 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 996 I/O threads are available 1023 worker and 996 I/O threads are available 1023 worker and 996 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 999 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 999 I/O threads are available 1023 worker and 999 I/O threads are available 1023 worker and 999 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 999 I/O threads are available 正如您所看到的,我的x4核心机器上可以使用所有工作线程,并且正在使用多个I / O线程. 作为TPL任务运行同步单向操作. 对于WCF合同: [ServiceContract] public interface IService2 { [OperationContract(IsOneWay = true)] void DoSomething(int value); } 让我们使用下一个代码运行从客户端到服务器的100个请求(只是想注意TPL使用CLR ThreadPool发动机罩): for (int i = 0; i < 100; i++) { int worker; int ioCompletion; ThreadPool.GetAvailableThreads(out worker,ioCompletion); Task.Run(() => client.DoSomething(i)); } 输出是: 1023 worker and 1000 I/O threads are available 1022 worker and 1000 I/O threads are available 1021 worker and 1000 I/O threads are available 1020 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 1019 worker and 1000 I/O threads are available 如您所见,现在正在使用工作线程,但不使用I / O线程. 那么,推荐的方法是什么? 总之,您的解决方案应该: >利用线程池中的工作线程和I / O线程(特别是对于高负载的应用程序)来防止出现瓶颈; 因此,推荐的方法是Task-based asynchronous pattern for WCF,满足上述所有要求. WCF的基于任务的异步模式. 合同: [ServiceContract] public interface IService3 { [OperationContract(IsOneWay = true)] Task DoSomethingAsync(int value); } 让我们再次发送100个请求: for (int i = 0; i < 100; i++) { int worker; int ioCompletion; ThreadPool.GetAvailableThreads(out worker,out ioCompletion); Console.WriteLine("{0} worker and {1} I/O threads are available",ioCompletion); client.DoSomethingAsync(i); } 输出: 1023 worker and 1000 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 999 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 999 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 999 I/O threads are available 1023 worker and 999 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 999 I/O threads are available 1023 worker and 998 I/O threads are available 1023 worker and 999 I/O threads are available (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |