异步 CTP - 如何使用 async/await 调用 wcf 服务?
如果我调用 WCF 服务方法,我会执行以下操作:
proxy.DoSomethingAsync();
proxy.DoSomethingAsyncCompleted += OnDoSomethingAsyncCompleted;
How can I do the same using the new async
ctp? 我想我需要像 proxy.DoSomethingTaskAsync
或 proxy.DoSomethingAsync().ToTask()
之类的东西? Web 服务调用需要返回一个 Task
才能使用 await
关键字,但是如何呢?
If I call a WCF service method I would do something like this:
proxy.DoSomethingAsync();
proxy.DoSomethingAsyncCompleted += OnDoSomethingAsyncCompleted;
How could I do the same using the new async
ctp?
I guess I would need something like proxy.DoSomethingTaskAsync
or proxy.DoSomethingAsync().ToTask()
? The web service call needs to return a Task<T>
to be able to use the await
keyword, but how??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在 CTP 中,有一些工厂方法可以将常规 APM 函数(开始/结束)转换为与新的 async 关键字兼容的函数,例如:
因此,在您的情况下,您可以执行等效操作,然后您就可以像这样称呼它:
请参阅此线程在 CTP 讨论组上了解更多信息
In the CTP there are factory methods that do the work of turning regular APM functions (Begin/End) into ones that are compatible with the new async keyword, for instance:
So in your case you can do the equivalent and then you'd then call it like so:
See this thread on the CTP discussion group for more info
使用 async-await 的异步服务响应速度非常快,因为它可以交错许多客户端调用并并行执行它们 (2)。
尽管如此,服务可以在一个线程 (3) 上完全线程安全地运行,并且可以是单例服务 (1) 或由框架仅为会话或调用创建的服务对象。
实现服务时,请注意 ServiceBehaviourAttributes (1)...(3) :
要在一个线程上运行每个调用,在您 Open() ServiceHost 时必须存在 System.Threading.SynchronizationContext.Current != null 。
使用 SynchronizationContext,您无需关心锁。原子的、不可中断的代码段大致从一个等待延伸到下一个等待。
请注意,共享服务数据在每次等待时都处于一致状态,并注意来自一个客户端的连续请求可能不会按照发送的顺序进行响应。
在客户端,异步服务操作是可等待的:
不可能在操作契约中使用 out 或 ref 参数。所有响应数据必须通过返回值Task(T)传递。
我在 AsyncWcfLib 中使用此接口,它支持 基于 Actor 的编程模型。
An asynchronous service using async-await is very responsive as it can interleave many client calls and execute them in parallel (2).
Despite this, the service can run fully thread-safe on one thread (3) and can be a singleton service (1) or a service object created by the framework for a session or a call only.
When implementing the service, please note the ServiceBehaviourAttributes (1)...(3) :
To run every call on one thread, a System.Threading.SynchronizationContext.Current != null must be present at the moment you Open() the ServiceHost.
Using the SynchronizationContext, you need not to care about locks. Atomic, non interruptable code sections stretch roughly from one await to the next.
Take care that shared service data is in a consistent state at every await and be aware that successive requests from one client may be responded not in the order they where sent.
On client side, the asynchronous service operation is awaitable:
It is not possible to use out or ref parameters in the operation contract. All response data must be passed by the returned value Task(T).
I use this interface in AsyncWcfLib, it supports a Actor based programming model.
异步 CTP 中有一个 WCF 示例,它将向您展示如何在 WCF 中使用异步/等待模型。
关于在WCF中支持该模型的计划,您可以查看以下帖子:
链接
希望这有帮助。
阿马德奥
There is a WCF sample in the Async CTP that will show you how to use the async/await model in WCF.
In terms of plans for supporting this model in WCF, you can take a look at the following post:
Link
Hope this helps.
Amadeo
正如 Matt 提到的,有一个
TaskFactory.FromAsync
方法允许您从Begin
/End
创建一个Task
代码>对。添加 WCF 引用时需要启用异步端点,然后您可以使用扩展方法自行包装它们。正如 Amadeo 提到的,异步 CTP 中的
(C# WCF) Stock Quotes
目录下有一个示例。另外,在该目录中,还有一个
TaskWsdlImportExtension
项目。添加对该 dll 的引用并修改您的 .config:然后您根本不必自己进行包装;
TaskWsdlImportExtension
将为您完成此操作。As mentioned by Matt, there is a
TaskFactory.FromAsync
method that allows you to create aTask
from aBegin
/End
pair. You need to enable asynchronous endpoints when you add your WCF reference, and then you can wrap them up yourself using extension methods.As mentioned by Amadeo, there is a sample of this in the Async CTP, under the
(C# WCF) Stock Quotes
directory.Also in that directory, there is a
TaskWsdlImportExtension
project. Add a reference to that dll and modify your .config as such:Then you don't have to do your own wrapping at all; the
TaskWsdlImportExtension
will do it for you.异步客户端调用同步服务是很常见的。
以下客户端和服务契约匹配(在幕后使用的一点魔法):
客户端接口是直接可等待的:
不可能在经营合同。所有响应数据都必须在返回值中传递。这对我来说实际上是一个突破性的改变。
我在 AsyncWcfLib 中使用此接口,它支持 基于 Actor 的编程模型。
It is quite common to have asynchronous clients calling a synchronous service.
The following client and service contracts match (a bit magic used behind the scenes):
The client interface is directly awaitable:
It is not possible to use out or ref parameters in the operaton contract. All response data must be passed in the return value. This actually was a breaking change for me.
I use this interface in AsyncWcfLib, it supports a Actor based programming model.
您正确地指出 async/await 是围绕返回 Task 和 Task 的方法构建的(有关 async/await 工作原理的详细说明,请参阅 此处)。以下是如何为 WCF 服务生成基于任务的方法:
Visual Studio 2012 RC 在“配置服务引用”对话框中具有一个附加复选框:“生成基于任务的操作”。虽然我没有在 中看到该选项MSDN,我希望它的存在是专门为了允许 WCF 调用上的无缝异步/等待。
对于早期版本,请查看 这篇文章,描述了一个允许生成任务<>的扩展基于 WCF 的方法,甚至使用 CTP。
You rightly point out that async/await are built around methods returning Task and Task (for a great explanation of the working of async/await, see here). Here's how to generate Task based methods for a WCF service:
Visual Studio 2012 RC has an additional check-box in the "Configure Service Reference" dialog box: "Generate task based operations". While I don't see that option documented in the MSDN, I expect it exists specifically to allow seamless async/await on WCF calls.
For earlier versions, take a look at this post, describing an extension which allows generating Task<> based methods on WCF even with the CTP.