我如何使用异步/等待调用web服务? [英] How can I use async/await to call a webservice?
问题描述
我写的 web服务 =http://www.yiiframework.com/doc/指南/ 1.1 / EN / topics.webservice> Yii的(PHP框架)。
我使用C#和Visual Studio 2012开发WP8应用程序。我添加了一个服务引用到我的项目(添加服务引用)。所以我能够使用Web服务的功能。
客户端=新YChatWebService.WebServiceControllerPortTypeClient();
client.loginCompleted + = client_loginCompleted; // this.token = e.Result;
client.loginAsync(this.username,this.password);
client.getTestCompleted + = client_getTestCompleted;
client.getTestAsync(this.token);
功能 getTestAsync
和 loginAsync
收益无效
无一不是异步的。有可能是功能回到任务< T>
?我想用异步
/ 等待
在我的程序的关键字。
答:
感谢您的帮助。
继。代码似乎工作
静态内部类扩展
{
私有静态无效TransferCompletion< T>(
TaskCompletionSource< T> TCS,System.ComponentModel.AsyncCompletedEventArgs E,
Func键< T>的getResult)
{
如果(e.Error = NULL)
{!
tcs.TrySetException(e.Error);
}
,否则如果(e.Cancelled)
{
tcs.TrySetCanceled();
}
,否则
{
tcs.TrySetResult(的getResult());
}
}
公共静态任务< loginCompletedEventArgs> LoginAsyncTask(这YChatWebService.WebServiceControllerPortTypeClient客户端,用户名字符串,字符串密码)
{
变种TCS =新TaskCompletionSource< loginCompletedEventArgs>();
client.loginCompleted + =(S,E)=> TransferCompletion(TCS,电子,()=> E);
client.loginAsync(用户名,密码);
返回tcs.Task;
}
}
我把它叫做这样
客户端=新YChatWebService.WebServiceControllerPortTypeClient();
变种登录=等待client.LoginAsyncTask(this.username,this.password);
假设loginAsync返回void,并loginCmpleted事件触发时登录完成后,这就是所谓的基于事件的异步模式,或EAP
要转换EAP等待/异步,咨询的Tasks和基于事件的异步模式。特别是,你要利用TaskCompletionSource到基于事件的模型转换为基于任务的模式。一旦你已经有了一个基于任务的模型,您可以使用C#5的性感等待功能
下面是一个例子:
//使用LoginCompletedEventArgs,或任何你需要什么了.loginCompleted事件
的//这是一个扩展方法,并且需要被放置在一个静态类。
公共静态任务< LoginCompletedEventArgs> LoginAsyncTask(这YChatWebService.WebServiceControllerPortTypeClient客户端,用户名字符串,字符串密码)
{
VAR TCS = CreateSource< LoginCompletedEventArgs>(NULL);
client.loginCompleted + =(发件人,E)=> TransferCompletion(TCS,电子,()=> E,NULL);
client.loginAsync(用户名,密码);
返回tcs.Task;
}
私有静态TaskCompletionSource< T> CreateSource< T>(对象状态)
{
返回新TaskCompletionSource< T>(
状态,TaskCreationOptions.None);
}
私有静态无效TransferCompletion< T>(
TaskCompletionSource< T> TCS,AsyncCompletedEventArgs E,
Func键< T>的getResult,动作unregisterHandler)
{
如果(e.UserState == TCS)
{
如果(e.Cancelled)tcs.TrySetCanceled();
,否则如果(e.Error!= NULL)tcs.TrySetException(e.Error);
,否则tcs.TrySetResult(的getResult());
如果(unregisterHandler!= NULL)unregisterHandler();
}
}
现在您已转换基于事件的异步编程模型以任务为基础的,现在可以使用等待:
VAR的客户=新YChatWebService.WebServiceControllerPortTypeClient();
变种登录=等待client.LoginAsyncTask(MyUserName输入,MYPASSWORD);
I have a webservice written in Yii (php framework).
I use C# and Visual Studio 2012 to develop a WP8 application. I added a service reference to my project (Add Service Reference). So I am able to use webservice functions.
client = new YChatWebService.WebServiceControllerPortTypeClient();
client.loginCompleted += client_loginCompleted; // this.token = e.Result;
client.loginAsync(this.username, this.password);
client.getTestCompleted += client_getTestCompleted;
client.getTestAsync(this.token);
function getTestAsync
and loginAsync
return void
and both are asynchronous. Is it possible for the functions to return Task<T>
? I would like to use async
/await
keywords in my program.
Answer:
Thank you for your help.
Following code seems to work.
internal static class Extension
{
private static void TransferCompletion<T>(
TaskCompletionSource<T> tcs, System.ComponentModel.AsyncCompletedEventArgs e,
Func<T> getResult)
{
if (e.Error != null)
{
tcs.TrySetException(e.Error);
}
else if (e.Cancelled)
{
tcs.TrySetCanceled();
}
else
{
tcs.TrySetResult(getResult());
}
}
public static Task<loginCompletedEventArgs> LoginAsyncTask(this YChatWebService.WebServiceControllerPortTypeClient client, string userName, string password)
{
var tcs = new TaskCompletionSource<loginCompletedEventArgs>();
client.loginCompleted += (s, e) => TransferCompletion(tcs, e, () => e);
client.loginAsync(userName, password);
return tcs.Task;
}
}
I call it this way
client = new YChatWebService.WebServiceControllerPortTypeClient();
var login = await client.LoginAsyncTask(this.username, this.password);
Assuming that loginAsync returns void, and loginCmpleted event fires when login is done, this is called the Event-based Asynchronous Pattern, or EAP.
To convert EAP to await/async, consult Tasks and the Event-based Asynchronous Pattern. In particular, you'll want to make use of the TaskCompletionSource to convert the event-based model to a Task-based model. Once you've got a Task-based model, you can use C# 5's sexy await feature.
Here's an example:
// Use LoginCompletedEventArgs, or whatever type you need out of the .loginCompleted event
// This is an extension method, and needs to be placed in a static class.
public static Task<LoginCompletedEventArgs> LoginAsyncTask(this YChatWebService.WebServiceControllerPortTypeClient client, string userName, string password)
{
var tcs = CreateSource<LoginCompletedEventArgs>(null);
client.loginCompleted += (sender, e) => TransferCompletion(tcs, e, () => e, null);
client.loginAsync(userName, password);
return tcs.Task;
}
private static TaskCompletionSource<T> CreateSource<T>(object state)
{
return new TaskCompletionSource<T>(
state, TaskCreationOptions.None);
}
private static void TransferCompletion<T>(
TaskCompletionSource<T> tcs, AsyncCompletedEventArgs e,
Func<T> getResult, Action unregisterHandler)
{
if (e.UserState == tcs)
{
if (e.Cancelled) tcs.TrySetCanceled();
else if (e.Error != null) tcs.TrySetException(e.Error);
else tcs.TrySetResult(getResult());
if (unregisterHandler != null) unregisterHandler();
}
}
Now that you've converted the Event-based async programming model to a Task-based one, you can now use await:
var client = new YChatWebService.WebServiceControllerPortTypeClient();
var login = await client.LoginAsyncTask("myUserName", "myPassword");
这篇关于我如何使用异步/等待调用web服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!