【问题标题】:How can I read return value from Async method in C#?如何从 C# 中的 Async 方法读取返回值?
【发布时间】:2018-11-14 09:21:34
【问题描述】:

我的async方法如下:

public async Task<List<object>> handleSummaryOfWallets()
{
    string token = giveMeToken("URL AND CREDS");

    Channel channel = new Channel("NANANANA GIROUD", ChannelCredentials.Insecure);

    OMGadminAPI.OMGadminAPIClient client = new OMGadminAPI.OMGadminAPIClient(channel);

    var summaryBalancesParams = new OMGadminAPIGetCurrenciesSummariesParams();

    summaryBalancesParams.AdminAuthTokenSecret = token;
    List<object> summariesCurrenciesOMGadmin = new List<object>();

    using (var call = client.GetCurrenciesSummaries(summaryBalancesParams))
    {
        while (await call.ResponseStream.MoveNext())
        {
            OMGadminAPICurrencySummary currencySummary = call.ResponseStream.Current;
            summariesCurrenciesOMGadmin.Add(currencySummary);
            Console.WriteLine(summariesCurrenciesOMGadmin);
        }
        return summariesCurrenciesOMGadmin;
    }
}

如您所见,上面的async 方法返回对象列表。我将这种方法称为如下:

var listOfBalances = balances.handleSummaryOfWallets().Wait();

它给了我错误:

错误 CS0815:无法将 void 分配给隐式类型变量

从错误中,我了解到这不是调用async 方法的正确方法。但我需要从async 获取的数据中读取准备好的对象列表。它的请求-响应,没有真正稳定的流。所以我只需要为每个请求生成一次这个列表。我正在使用 gRPC 框架进行 RPC 调用。

请帮我获取这些数据并准备好使用。

【问题讨论】:

标签: c# asynchronous async-await grpc


【解决方案1】:

Task.Wait 方法等待Task 完成执行。它返回void。这就是异常的原因。

现在要克服异常并读取返回值,一种方法是在其他答案和 cmets 中提到; await调用如下:

public async void TestAsync()
{
    var listOfBalances = await handleSummaryOfWallets();
}

请注意,您的调用方法现在也应该是async 方法。

当您在代码中调用Wait 时,看起来您想要立即得到结果;你没有其他事情要做,这不取决于结果。在这种情况下,您可以选择通过调用Wait 来停止async 链。但是你需要做一些改变如下:

public void TestAsync()
{
    var task = handleSummaryOfWallets();//Just call the method which will return the Task<List<object>>.
    task.Wait();//Call Wait on the task. This will hold the execution until complete execution is done.
    var listOfBalances = task.Result;//Task is executed completely. Read the result.
}

请注意,调用方法不再是async。其他解释见code-cmets。

上述代码的其他简短替代如下:

public void TestAsync()
{
    var listOfBalances = handleSummaryOfWallets().Result;
}

【讨论】:

    【解决方案2】:

    只需在调用您的方法时使用await

    var listOfBalances = await balances.handleSummaryOfWallets();
    

    【讨论】:

    • 由于 handleSummaryOfWallets 正在调用 I/O 操作并且 awaiting 它是响应,它是正确的 async 并且不适合启动另一个基于 CPU 的任务来运行它。
    • 你错过了问题中的代码吗?它将方法声明为 public async Task&lt;List&lt;object&gt;&gt; handleSummaryOfWallets()... 或者您是否建议 OP 使其不异步?
    • @Chris 啊,我没有在方法中看到 await。谢谢
    猜你喜欢
    • 1970-01-01
    • 2016-03-27
    • 2016-12-12
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-18
    相关资源
    最近更新 更多