Rob*_*ert 2 c# asynchronous restsharp
在处理使用异步 rest 调用的数据 API 时(我使用的是 RestSharp.Portable),处理返回值的最佳方法是什么?由于 async 函数只能返回一个 Task 或 Task ......但调用者无法返回返回值...... API如何将数据返回给调用者?全局属性?
从我到目前为止所读到的内容来看,回调函数似乎是与响应数据交互的唯一方法?
以下面的方法为例;以前我没有使用异步 Rest 库并且能够返回一个值,但是在将其转换为使用 RestSharp.Portable 后,我没有看到返回值的方法:
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;
}
Run Code Online (Sandbox Code Playgroud)
在这里我所能做的就是返回 Task 但调用者仍然无法获取响应数据,或者我是否遗漏了一些明显的东西?调用者可以订阅在 Task.Completed 等处触发的事件吗?
我对这个异步概念非常模糊。是否有编写可移植数据 API 的示例?
我认为您真的需要退后一步阅读有关如何使用async
和await
关键字的信息。除其他事项外,您需要了解编码async
方法时在幕后发生的一些编译器魔术。
这是一个很好的起点:使用 Async 和 Await 进行异步编程。
更多关于您的问题,返回类型和参数部分有这样的说法:
您指定
Task<TResult>
的返回类型,如果该方法中包含一个Return
(Visual Basic)或return
(C#)语句,指定类型的操作数TResult。
然后给出以下代码示例:
// Signature specifies Task<TResult>
async Task<int> TaskOfTResult_MethodAsync()
{
int hours;
// . . .
// Return statement specifies an integer result.
return hours;
}
Run Code Online (Sandbox Code Playgroud)
请注意,尽管方法返回类型为Task<int>
,但该return
语句仅返回一个int
,而不是一个Task<int>
。这基本上是因为有一些编译器魔法正在进行,这使得这仅在async
方法中合法。
不想深入了解所有细节,您还应该知道async
方法的调用者通常会使用await
关键字来这样做,该关键字知道如何处理Task
orTask<TResult>
返回值并自动为您解开实际的预期返回值一种透明的方式(幕后更多的编译器魔法)。
所以对于上面的例子,这里是一种调用方式:
int intValue = await TaskOfTResult_MethodAsync(); // Task<int> is automatically unwrapped to an int by the await keyword when the async method completes.
Run Code Online (Sandbox Code Playgroud)
或者,如果您希望启动异步方法,在此期间执行一些其他工作,然后等待异步方法完成,可以这样做:
Task<int> t = TaskOfTResult_MethodAsync();
// perform other work here
int intValue = await t; // wait for TaskOfTResult_MethodAsync to complete before continuing.
Run Code Online (Sandbox Code Playgroud)
希望这能让您大致了解如何从异步方法传回值。
对于您的具体示例,我不熟悉 RestSharp(从未使用过)。但从我读到的一点点来看,我认为你会想要使用client.ExecuteTaskAsync<T>(request)
而不是client.ExecuteAsync<T>(request, callback)
更好地适应async-await
模型。
我认为你的方法看起来像这样:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
您的调用代码将如下所示:
EntityResourceDescriptor erd = await GetEntityDescriptor("entityType");
Run Code Online (Sandbox Code Playgroud)
我希望你设法让这个工作。但同样,请务必阅读有关async-await
编程风格的文档。一旦您将头脑围绕为您完成的编译器魔术,它就非常整洁。但是,如果您不花时间真正了解它的工作原理,就很容易迷路。