从 WCF 服务调用异步方法
Posted
技术标签:
【中文标题】从 WCF 服务调用异步方法【英文标题】:Calling async methods from a WCF service 【发布时间】:2014-04-30 16:17:07 【问题描述】:我想,例如:
[ServiceContract]
interface IService
[OperationContract]
int SomeMethod(int data);
int SomeMethod(int data)
var query = ... build LINQ query;
var response = await query.ToListAsync();
return response.Length;
我不想将async
添加到IService
接口或SomeMethod
方法中。使用异步方法是一个内部问题,不应反映在接口中。
我该怎么做?
澄清:
我的问题是在非async
方法中使用await
。我不希望服务合同发生变化(客户端不一定知道async
是什么),我也不希望将方法拆分为BeginSomeMethod
和EndSomeMethod
。我想要一种使用await
内部的方法。
【问题讨论】:
相关:***.com/q/22623922/1768303 【参考方案1】:服务器使用的是同步还是异步代码对客户端来说并不重要。客户端和服务器由明确指定的有线协议(通常是 SOAP)分隔。 SOAP 没有异步完成的概念。
您可以拥有一个同步服务器和一个异步客户端,反之亦然。 客户端甚至无法检测服务器是同步还是异步。这是一个实现细节。服务器可能是运行 Linux 的手表,但您仍然无法分辨。
您使用的 IO 样式是一个实现细节,不会影响通过网络传输的字节数。
所以选择你喜欢的。客户端仍然可以使用异步 IO 访问服务器。
我不知道为什么这会让人们如此惊讶。在其他情况下,这似乎非常直观:您可以拥有一个异步 TCP 服务器和一个同步客户端。我可以说new WebClient().DownloadString(url)
并从以异步方式实现的网络服务器同步下载字符串。我什至不知道正在运行什么服务器软件。
在进行 WCF 调用时,使用 Fiddler 查看通过线路传输的内容。没有同步或异步调用的概念。
在后台,当您异步调用服务时,WCF 客户端库以异步方式使用 TCP 套接字。当您同步调用时,TCP 套接字与阻塞调用一起使用。这就是全部区别。
除了同步方法之外,WCF 生成的客户端还可以具有异步方法。在 UI 中选择“生成异步操作”选项。现在你有两个版本。两者功能齐全。
您可以通过以下实验来说服自己:编写一个同步服务器,并从同一个 .NET 客户端同时调用它同步和异步。现在异步编写第二个服务器(以您喜欢的任何样式)并使用完全相同的客户端代码来调用它。
Task
和 IAsyncResult
无论如何都不能通过 SOAP 序列化,因此不可能将 Task
传输到客户端。
【讨论】:
我不认为这回答了@zmbq 在comment 中指出的目标:“根据定义,该方法是一个长时间执行的方法。不希望阻塞的客户端将需要实现他们自己的异步机制。我希望在服务器中使用异步,而不管客户端如何(例如,客户端可能正在运行 .NET 4,根本不支持异步/等待)。” 我认为我的答案是:) 他可以在服务器上使用异步,不管客户端做什么。客户端可以同步调用异步服务器。不需要 Task.Wait 或类似的东西。每个生成的 WCF 客户端都有同步和异步调用的方法。两者都工作正常。 让我这么说吧,如果 API 在服务器上启动异步操作(称为SomeMethodStart
),它如何通知客户端其完成?将有一个客户端代理 BeginSomeMethodStart
和 EndSomeMethodStart
方法,但在客户端调用 EndSomeMethodStart
将在 SomeMethodStart
返回服务器后立即返回,而不是在服务器端异步操作结束时返回。他需要的是正确地向客户端公开服务器端的async操作,并且能够在服务器上使用async/await
而不阻塞。该服务需要公开 APM 或 TAP API。
当(异步)服务器完成处理时,它会发送响应。 BeginXXX 方法完成后不会发送任何响应。没有一个字节。 EndXXX 方法在服务器上完成后响应。 calling EndSomeMethodStart on the client will return as soon as SomeMethodStart returns on the server
不 - 它在响应到达时返回。在服务器完成all 处理后响应到达。试试吧。用 Fiddler 观察。
@usr,我已经玩过了。我确实学到了一些新东西,我得到了纠正,非常感谢。以上是关于从 WCF 服务调用异步方法的主要内容,如果未能解决你的问题,请参考以下文章
对 WCF 服务的异步调用不会保留 CurrentCulture