等待异步澄清

时间:2014-02-11 19:46:40

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

我正在尝试学习/了解更多有关C#中的async / await的内容,我会将自己置于新手类别中,欢迎您提出所有意见/建议。我写了一个小测试,以便更好地理解和澄清await / async。我的程序在“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());
        }

    }
}

2 个答案:

答案 0 :(得分:4)

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

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

有关详细信息,请参阅我的async/await intro

答案 1 :(得分:2)

冻结的罪魁祸首是:

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

Task构造函数无法启动任务,因此您正在创建未运行的Task。在await GetStringLengthvar result = new Task<int>(() => { return pageData.Length; }); result.Start(); return result; 时,您将永远等待结果。

您可以手动启动任务:

Task.Run

或使用return Task.Run(() => { return pageData.Length; }); 静态方法,它将创建并启动任务:

{{1}}