我目前正在将客户端应用程序迁移到.NET 4.5以使用async/await.该应用程序是WCF服务的客户端,该服务目前仅提供同步服务.我现在想知道,我应该如何异步使用这种同步服务?
我使用渠道工厂连接到WCF服务,利用服务器和客户端共享的服务合同.因此,我无法使用VisualStudio中的自动生成或svcutil生成异步客户端代理.
我已经阅读了这个相关的问题,该问题是关于是否在客户端使用包装同步调用Task.Run,或者是否使用异步方法扩展服务契约.答案表明,服务器提供的"真正的"异步方法对于客户端性能更好,因为没有线程必须主动等待服务调用完成.这对我来说很有意义,这意味着同步调用应该包含在服务器端.
另一方面,Stephen Toub在这篇博客文章中一般都不赞成这样做.现在,他没有在那里提到WCF,所以我不确定这是否适用于在同一台机器上运行的库,或者它是否也适用于远程运行的东西,但是异步性的引入对它的实际影响是连接/传输.
毕竟,由于服务器实际上并不是异步工作(并且可能不会在另一个时间内工作),因此一些线程将始终必须等待:在客户端或服务器上.这同样适用于同步使用服务(当前,客户端在后台线程上等待以保持UI响应).
为了使问题更清楚,我准备了一个例子.完整项目可在此处下载.
服务器提供同步服务GetTest.这是当前存在的,并且工作同步发生的地方.一种选择是将其包装在异步方法中,例如使用Task.Run,并将该方法作为合同中的附加服务提供(需要扩展合同接口).
// currently available, synchronous service
public string GetTest() {
Thread.Sleep(2000);
return "foo";
}
// possible asynchronous wrapper around existing service
public Task<string> GetTestAsync() {
return Task.Run<string>(() => this.GetTest());
}
// ideal asynchronous service; not applicable as work is done synchronously
public async Task<string> GetTestRealAsync() {
await Task.Delay(2000);
return "foo";
} …Run Code Online (Sandbox Code Playgroud) 我想从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;
}
Run Code Online (Sandbox Code Playgroud)
我不想添加async到IService界面或SomeMethod方法.使用异步方法是一个内部问题,不应该在接口中反映出来.
我怎样才能做到这一点?
澄清:
我的问题是await在非async方法中使用.我不希望服务合同发生变化(客户端不一定知道是什么async),我不想将方法拆分为BeginSomeMethod和EndSomeMethod.我想要一种await 内部使用的方法.