我想从 WCF 服务调用异步方法,例如:
[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
接口(interface)或 SomeMethod
方法。使用异步方法是一个内部问题,不应反射(reflect)在界面中。
我该怎么做?
澄清:
我的问题是在非async
方法中使用await
。我不希望服务契约发生变化(客户端不一定知道什么是 async
),我也不想将方法拆分为 BeginSomeMethod
和EndSomeMethod
。我想要一种使用await
内部的方法。
最佳答案
服务器是使用同步代码还是异步代码对客户端来说并不重要。客户端和服务器由明确指定的线路协议(protocol)(通常是 SOAP)分隔。 SOAP 没有异步完成的概念。
您可以有一个同步服务器和一个异步客户端,反之亦然。 客户端甚至无法检测服务器是同步还是异步。这是一个实现细节。服务器可能是一 block 运行 Linux 的 watch ,但您仍然无法分辨。
您使用的 IO 样式是一个实现细节,不会影响通过网络传输的字节。
所以选择你喜欢的。客户端仍然可以使用异步 IO 访问服务器。
我不确定为什么这会让人们如此惊讶。在其他情况下,这似乎非常直观:您可以拥有一个异步 TCP 服务器和一个同步客户端。我可以说 new WebClient().DownloadString(url)
并从以异步方式实现的 Web 服务器同步下载字符串。我什至不知道正在运行什么服务器软件。
当您进行 WCF 调用时,使用 Fiddler 查看在线路上发生了什么。没有同步或异步调用的概念。
在后台,当您异步调用服务时,WCF 客户端库以异步方式使用 TCP 套接字。当您同步调用时,TCP 套接字将用于阻塞调用。这就是全部区别。
除了同步方法之外,WCF 生成的客户端还可以具有异步方法。在 UI 中选择“生成异步操作”选项。现在你有两个版本。两者都功能齐全。
以下是您可以通过实验让自己相信这一点的方法:编写一个同步服务器,并从同一个 .NET 客户端调用它的同步和异步。现在异步编写第二个服务器(以您喜欢的任何样式)并使用完全相同的客户端代码来调用它。
Task
和 IAsyncResult
无论如何都不能通过 SOAP 序列化,因此不可能将 Task
传输到客户端。
关于c# - 从 WCF 服务调用异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22590239/