如何处理异步函数中的返回值 [英] How to handle return values in async function

查看:177
本文介绍了如何处理异步函数中的返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在处理使用异步Rest调用的数据API(我正在使用RestSharp.Portable)时,处理返回值的最佳方法是什么?由于异步函数只能返回一个Task或Task ...,但是调用者无法返回到返回值... API如何将数据返回给调用者?全球属性?

When working on data APIs which use async rest calls (I am using RestSharp.Portable), what is the best way to handle return values? Since async function can only return a Task or Task ... but the caller has no way to getting back to the return value ... how would the API return data back to the caller? Global properties?

从到目前为止的内容来看,似乎回调函数是与Response Data交互的唯一方法?

From what I have read so far, it appears that callback functions are the only way to interact with Response Data?

以下面的方法为例;以前我没有使用异步Rest库,但是能够返回一个值,但是将其转换为使用RestSharp.Portable之后,我看不到返回值的方法:

Take the following method for example; previously I was not using async Rest library and was able to return a value but after converting it to use RestSharp.Portable, I dont see a way to return the value:

public async Task<EntityResourceDescriptor> GetEntityDescriptor(string entityType)
    {
        TaskCompletionSource<EntityResourceDescriptor> tcs = new TaskCompletionSource<EntityResourceDescriptor>();
        var req = new RestRequest("/qcbin/rest/domains/{domain}/projects/{project}/customization/entities/{entityType}");
        AddDomainAndProject(req);
        req.AddParameter("entityType", entityType, ParameterType.UrlSegment);
        client.ExecuteAsync<EntityResourceDescriptor>(req, (res) =>
            {
                if (res.ResponseStatus == ResponseStatus.Error)
                {
                    tcs.TrySetException(res.ErrorException);
                }
                else
                {
                    tcs.SetResult(res.Data);
                }
            }
        );
        return tcs.Task;
    }

这里我所能做的就是返回Task,但是调用者仍然无法获取响应数据,或者我是否缺少明显的东西?呼叫者可以预订在Task.Completed等处触发的事件吗?

Here all I can do is return Task but the caller still has no way to get to the response data or am I missing something obvious? Can the caller subscribe to an event which gets fired at Task.Completed etc.?

我对这个异步概念非常模糊.有编写便携式数据API的示例吗?

I am very fuzzy on this async concept. Are there any examples of writing Portable data APIs?

推荐答案

我认为您确实需要退后一步,了解如何使用 async await 关键字.除其他外,您需要了解在编码 async 方法时在幕后发生的一些编译器魔术.

I think you'll really need to take a step back and read about how to use the async and await keywords. Among other things, you'll need to understand some of the compiler magic that happens behind the scenes when coding async methods.

这里是一个不错的起点:使用Async和Await进行异步编程.

Here is a good place to start: Asynchronous Programming with Async and Await.

关于您的问题的更多信息,返回类型和参数该部分说:

More to your question, the Return Types and Parameters section has this to say:

如果方法包含 Return (Visual Basic)或 return (C#)语句,则将 Task< TResult> 指定为返回类型指定类型为 TResult 的操作数.

You specify Task<TResult> as the return type if the method contains a Return (Visual Basic) or return (C#) statement that specifies an operand of type TResult.

然后提供以下代码示例:

It then gives the following code example:

// Signature specifies Task<TResult>
async Task<int> TaskOfTResult_MethodAsync()
{
    int hours;
    // . . .
    // Return statement specifies an integer result.
    return hours;
}

请注意,尽管方法返回类型为 Task< int> ,但是 return 语句仅返回 int 而不是任务< int> .这基本上是因为发生了一些编译器魔术,使该魔术仅在 async 方法中才合法.

Notice how despite the method return type of Task<int>, the return statement simply returns an int, not a Task<int>. That's basically because there is some compiler magic going on that makes this legal only in async methods.

不想进入所有细节,您还应该知道通常希望使用 await 关键字来调用 async 方法的调用者,该关键字知道如何处理 Task Task< TResult> 返回值,并以透明的方式自动为您自动包装实际的期望返回值(幕后更多的编译器魔术).

Without wanting to get into all the details, you should also know that the caller of the async method is normally expected to do so using the await keyword, which knows how to deal with the Task or Task<TResult> return values and automatically unwraps the actual expected return value for you in a transparent manner (more compiler magic behind the scenes).

因此对于上面的示例,这是一种调用方式:

So for the above example, here is one way to call it:

int intValue = await TaskOfTResult_MethodAsync(); // Task<int> is automatically unwrapped to an int by the await keyword when the async method completes.

或者,如果您希望启动async方法,同时执行一些其他工作,然后等待async方法完成,则可以这样完成:

Or, if you wish to start the async method, perform some other work in the meantime, and then wait for the async method to complete, this can be done like this:

Task<int> t = TaskOfTResult_MethodAsync();
// perform other work here
int intValue = await t; // wait for TaskOfTResult_MethodAsync to complete before continuing.

希望这使您大致了解如何从异步方法传回值.

Hopefully this gives you a general idea of how to pass values back from an async method.

对于您的特定示例,我不熟悉RestSharp(从未使用过).但是,从我读过的书中,我想您将要使用 client.ExecuteTaskAsync< T>(请求)而不是 client.ExecuteAsync< T>(请求,回调)>以更好地适应 async-await 模型.

For your specific example, I am not familiar with RestSharp (never used it). But from what little I read, I think you'll want to use client.ExecuteTaskAsync<T>(request) instead of client.ExecuteAsync<T>(request, callback) to better fit in the async-await model.

我认为您的方法应该看起来像这样:

I'm thinking your method would instead look something like this:

public async Task<EntityResourceDescriptor> GetEntityDescriptor(string entityType)
{
    var req = new RestRequest("/qcbin/rest/domains/{domain}/projects/{project}/customization/entities/{entityType}");
    AddDomainAndProject(req);
    req.AddParameter("entityType", entityType, ParameterType.UrlSegment);
    var res = await client.ExecuteTaskAsync<EntityResourceDescriptor>(req);

    if (res.ResponseStatus == ResponseStatus.Error)
    {
        throw new Exception("rethrowing", res.ErrorException);
    }
    else
    {
        return res.Data;
    }
}

您的调用代码将如下所示:

Your calling code would then look like this:

EntityResourceDescriptor erd = await GetEntityDescriptor("entityType");

希望您能成功进行这项工作.但同样,请确保阅读有关 async-await 编程风格的文档.一旦您将头放在为您完成的编译器魔术上,这将非常整洁.但是,如果您不花时间真正了解它的工作原理,那么很容易迷路.

I hope you manage to get this working. But again, make sure to read the documentation about the async-await style of programming. It's very neat once you wrap your head around the compiler magic that is done for you. But it's so easy to get lost if you don't take the time to really understand how it works.

这篇关于如何处理异步函数中的返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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