如何使用 async/await 调用网络服务? [英] How can I use async/await to call a webservice?

查看:28
本文介绍了如何使用 async/await 调用网络服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用 Yii(php 框架).

I have a webservice written in Yii (php framework).

我使用 C# 和 Visual Studio 2012 来开发 WP8 应用程序.我向我的项目添加了一个服务引用(添加服务引用).这样我就可以使用网络服务功能了.

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 getTestAsyncloginAsync 返回 void 并且两者都是异步的.函数是否有可能返回 Task?我想在我的程序中使用 async/await 关键字.

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.

推荐答案

假设 loginAsync 返回 void,并且在登录完成时触发 loginCmpled 事件,这称为基于事件的异步模式,或 EAP.

Assuming that loginAsync returns void, and loginCmpleted event fires when login is done, this is called the Event-based Asynchronous Pattern, or EAP.

要将 EAP 转换为等待/异步,请参阅 任务和基于事件的异步模式.特别是,您需要使用 TaskCompletionSource 将基于事件的模型转换为基于任务的模型.一旦你有了一个基于任务的模型,你就可以使用 C# 5 的性感等待功能.

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.

这是一个例子:

// 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();
    } 
}

既然您已将基于事件的异步编程模型转换为基于任务的异步编程模型,您现在可以使用 await:

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");

这篇关于如何使用 async/await 调用网络服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆