【问题标题】:Await async clarification等待异步澄清
【发布时间】:2014-03-09 19:28:23
【问题描述】:

我正在尝试学习/理解更多关于 C# 中的 async/await 的信息,我会将自己归为菜鸟类别,因此欢迎您提出所有 cmets/建议。我写了一个小测试来更好地理解和澄清等待/异步。我的程序在“GetStringLength”调用后冻结了我尝试阅读几件事,但看起来我被卡住了,我想就我可能做错的事情征求专家意见。你能在这里指导我或指出我正确的方向吗?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AsyncPatterns
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            Task<string> url = p.FindLargtestWebPage(new Uri[]{new Uri("http://www.google.com"), 
                                                            new Uri("http://www.facebook.com"), 
                                                            new Uri("http://www.bing.com") });
            Console.WriteLine(url.Result);
            Console.ReadLine();
        }

        public async Task<string> FindLargtestWebPage(Uri[] uris)
        {
            string highCountUrl = string.Empty;
            int maxCount = 0;

            foreach (Uri uri in uris)
            {
                Console.WriteLine(string.Format("Processing {0}", uri.ToString()));
                var pageContent = await GetWebPageString(uri);
                var count = await GetStringLength(pageContent);
                if (count > maxCount)
                {
                    highCountUrl = uri.ToString();
                }
            }
            return highCountUrl;            
        }

        public async Task<int> GetStringLength(string pageData)
        {
            Console.WriteLine("Getting length");
            return await new Task<int>(() =>
            {
                return pageData.Length;
            });
        }

        public async Task<string> GetWebPageString(Uri uri)
        {
            WebClient webClient = new WebClient();
            Console.WriteLine("Downloading string");
            return await webClient.DownloadStringTaskAsync(uri.ToString());
        }

    }
}

【问题讨论】:

标签: .net async-await c#-5.0


【解决方案1】:

不要在async 代码中使用Task 构造函数,只有在有异步工作要做时才使用asyncGetStringLength 没有异步工作要做,所以应该是:

public int GetStringLength(string pageData)
{
  Console.WriteLine("Getting length");
  return pageData.Length;
}

更多信息,请查看我的async/await intro

【讨论】:

  • 谢谢!!欣赏。
【解决方案2】:

冻结的罪魁祸首是这样的:

return await new Task<int>(() =>
{
    return pageData.Length;
});

Task 构造函数不会启动任务,因此您正在创建一个未运行的Task。当您在 GetStringLengthawait 时,您将永远等待结果。

您可以手动启动任务:

var result = new Task<int>(() =>
{
    return pageData.Length;
});

result.Start();

return result;

或者使用Task.Run静态方法,它会创建并启动任务:

return Task.Run(() =>
{
    return pageData.Length;
});

【讨论】:

  • 或者像斯蒂芬所说的那样只拥有一个同步版本的 GetStringLength。除非 OP 在实际代码中具有其他逻辑,否则我看不到在这里使用异步的理由。
  • 谢谢!!欣赏它。感谢您指出为什么它冻结的原因,出于同样的原因,我接受这个作为答案!
  • @KaiWang:OP 特别说他们正在试验async/await,所以我把这个问题读作“我怎样才能让它工作”,而不是关于代码如何工作的问题应该写出来。正如你所说,这不应该是“真实”代码中的async 方法:)
  • @Porges,对不起,我的错。
  • @KaiWang,不错,我可能应该澄清一下
猜你喜欢
  • 2013-06-27
  • 2013-06-12
  • 1970-01-01
  • 2023-03-12
  • 2018-08-24
  • 2016-07-07
  • 2016-03-25
  • 2017-10-09
相关资源
最近更新 更多