【问题标题】:Why does the method return a string when return type is Task<string>?为什么返回类型为Task<string>的方法返回一个字符串?
【发布时间】:2015-09-04 02:15:53
【问题描述】:

我有一个关于 C# 中的异步编程的问题。我想知道为什么返回类型为 Task 的函数必须返回一个字符串。 因此,即使我返回了一个字符串,它也会再次被包装到一个任务中 - 为什么会这样?

问题是我必须向学生解释这些东西。即使我刚刚等待函数返回的结果,将返回的字符串包装在 Task 对象中的原因是什么?我认为 await 语句会阻止该方法的继续执行,直到结果到达 - 这意味着在函数调用 (await GetWeatherAsync()) 时没有什么可以等待,因为结果已经存在......

这是我的示例代码:

    static async void Download()
    {
        //I have just awaited the result in the function call. Why do I have to do this again at this point?
        Console.WriteLine(await GetWeatherAsync());
    }

    private static async Task<string> GetWeatherAsync()
    {
        HttpClient client = new HttpClient();
        Task<HttpResponseMessage> t = client.GetAsync("http://localhost:59534/WeatherService.svc/rest?weekDay=Monday");
        HttpResponseMessage serverResponse = await t;

        return await serverResponse.Content.ReadAsStringAsync();
    }

如果最后没有等待,至少一切对我来说都是有意义的——因为我会返回一个可能仍有工作要做的真正任务......

【问题讨论】:

  • 简而言之:Task 返回一个string。该方法返回Task
  • 啊是的...让我重命名它
  • 是什么让您认为GetWeatherAsync() 没有返回Task&lt;string&gt;?尝试在没有async 运算符的情况下调用它,您将得到一个Task&lt;string&gt; 对象。

标签: c# .net asynchronous async-await


【解决方案1】:

当您将一个方法标记为async Task&lt;string&gt; 时,您是在告诉它的使用者该方法承诺将来会返回一个string

我认为您对 await 关键字感到困惑。 await 关键字允许您暂停执行您的方法,直到等待的任务完成,将其(对消费者)视为同步方法。

你可以有一个简单的异步方法:

static async Task<string> SayHi()
{
    return "hi";
}

您可以使用:

await SayHi() //returns a string

SayHi() //returns a Task<string>

除了 await 的所有好处外,它还会在完成时为您解开您的 Task,这是有道理的,因为它等待您的 Task 完成,剩下的就是结果。

【讨论】:

  • 是的!感谢那!我现在完全明白了:)
【解决方案2】:

因为异步方法不返回值。当计算完成时,它们返回承诺返回值。方法在计算完成之前立即返回,在实际字符串生成之前。

【讨论】:

  • 所以你是说 GetWeatherAsync() 方法在 await serverResponse... 被调用后立即返回?很奇怪,因为 MSDN 说:“await 运算符应用于异步方法中的任务,以暂停该方法的执行,直到等待的任务完成。” msdn.microsoft.com/en-us/library/hh156528.aspx
  • @FunkyPeanut 无需等待即可调用它
  • @FunkyPeanut 你可以认为你的代码行相当于:Task&lt;string&gt; tmp = GetWeatherAsync(); Console.WriteLine(await tmp);,所以对GetWeatherAsync的调用在Console.WriteLine()之前完成,那么Console.WriteLine必须等待调用结果 (await)
  • 啊!我可以发誓我之前在没有等待的情况下尝试它时出错了......现在我明白了......当我只想返回一个任务时,我必须从函数中删除“异步”关键字,对吗?跨度>
  • @FunkyPeanut 如果您的方法包含 await 关键字,那么它必须包含 async 修饰符。 async 修饰符将方法标记为必须在编译期间修改的方法(在状态机中进行转换)
猜你喜欢
  • 1970-01-01
  • 2020-06-14
  • 1970-01-01
  • 1970-01-01
  • 2017-09-01
  • 1970-01-01
  • 2016-04-19
  • 1970-01-01
  • 2021-11-25
相关资源
最近更新 更多