-1

我创建了一个C# Restsharp 客户端来使用同步调用对我的 API 进行查询。同步调用按应有的方式工作,但是我的异步调用从不返回任何内容。await 运算符应暂停对封闭 async 方法的评估,直到其操作数表示的异步操作完成。当异步操作完成时,等待操作符返回操作的结果。但是,就我而言,这从未发生过。我现在已经搜索了整个堆栈溢出,但我无法弄清楚为什么我的异步调用不会返回任何内容。谁能发现可能导致问题的原因以及我该如何解决?这是我的设置:

客户端方法:

public class Objects{

    private readonly IRestClient _restClient;

    public Objects(IRestClient restClient)
    {
        _restClient = restClient;
    }

    public async Task< List<ObjectGet> CreateObjects(List<ObjectBase>> objects, Boolean createCdfFile = true)
    {

        var request = new RestRequest("/objects/", Method.POST) { RequestFormat = DataFormat.Json };

        var objectsJson = JsonConvert.SerializeObject(objects, Formatting.Indented);
        request.AddParameter("create_cdf_file", createCdfFile, ParameterType.QueryString)
               .AddParameter("application/json", objectsJson, ParameterType.RequestBody);

        IRestResponse<List<ObjectGet>> response = await _restClient.ExecuteAsync<List<ObjectGet>>(request);

        return response.Data;
    }
}

我的同步调用有效:

var obj = _restClient.FetchAllObjects(filter).GetAwaiter().GetResult();

返回: System.Collections.Generic.List1[RestsharpApiClient.model.ObjectWithRelationships]

我的异步调用执行,但是..

var obj = _restClient.FetchAllObjects(filter);

从不返回任何东西

但是,如果按顺序在同步调用之前运行异步调用,它们都会返回正确的结果:

var obj = _restClient.FetchAllObjects(filter);
var objAsync = _restClient.FetchAllObjects(filter).GetAwaiter().GetResult();

返回:

System.Collections.Generic.List1[RestsharpApiClient.model.ObjectWithRelationships] , System.Collections.Generic.List1[RestsharpApiClient.model.ObjectWithRelationships]

这是我的项目文件

TargetFramework=netstandard2.0
<LangVersion>8.0</LangVersion>
"Newtonsoft.Json" Version="12.0.3"
"RestSharp" Version="106.11.4"

非常感谢任何帮助

4

2 回答 2

0

它尝试执行并退出[原文如此],在这一行代码为 0。

当然,一旦达到一个连续点,程序流就会返回到您的调用函数,其余代码会做一些事情(在您的情况下,很可能它使用线程池线程来构建响应)。

当你到达终点时会发生什么Main?您的程序退出。

现在你当然不会展示你是如何调用它的,但是从你展示的代码模式来看,我很肯定你正在使用同步异步反模式。不。曾经。Main async正确地声明你await的电话,你会得到你想要的。

于 2020-07-27T15:06:56.167 回答
0

从我可以从评论中推断出,你有这样的事情:

static void Main(string[] args)
{
    Program prog = new Program();
    prog.OnStart();
}

class Program
{
    private async void OnStart()
    {
        var obj = await _restClient.FetchAllObjects(filter);
        Console.Writeline(obj);
    }
}

FetchAllObjects返回Task<List<ObjectWithRelationships>>,因此通过 using await,结果List<ObjectWithRelationships>将在Task完成时展开,形成objtype List<ObjectWithRelationships>

但是, usingawait也会导致您的OnStart方法返回,调度一个延续,并且因为它是声明void的,您的Main方法不知道它需要等待并且将在FetchAllObjects完成之前继续退出。

您需要Task从以下位置返回OnStart

private async Task OnStart()

现在当await被击中时,OnStart将返回一个Taskto Main

您的Main方法现在可以等待Task完成:

static void Main(string[] args)
{
    Program prog = new Program();
    prog.OnStart().GetAwaiter().GetResult();
}

如果您使用的是 C#7.1+,则可以使用async Main

static async Task Main(string[] args)
{
    Program prog = new Program();
    await prog.OnStart();
}

这只是语法糖:

static void Main(string[] args) => MainAsync(args).GetAwaiter.GetResult();

private static async Task MainAsync()
{
    Program prog = new Program();
    await prog.OnStart();
}
于 2020-07-27T16:08:59.667 回答