Await async clarification

拟墨画扇 提交于 2019-12-24 12:21:23

问题


I am trying to learn/understand more about async/await in C# and I would put myself in rookie category so all your comments/suggestions are welcome. I wrote small test to have better understanding and clarification about await/async. My program freezes after "GetStringLength" call I tried reading several things but looks like I am stuck and I thought of taking expert opinion on what I might be doing wrong. Can you please guide me or point me in right direction here?

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());
        }

    }
}

回答1:


The culprit for freezing is this:

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

This Task constructor doesn't start the task, so you're creating a Task that isn't running. When you await on it in GetStringLength you're going to be waiting forever for the result.

You can either start the task manually:

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

result.Start();

return result;

or use the Task.Run static method, which will create and start the task:

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



回答2:


Do not use the Task constructor in async code, and only use async when you have asynchronous work to do. GetStringLength has no asynchronous work to do, so it should be:

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

For more information, see my async/await intro.



来源:https://stackoverflow.com/questions/21711548/await-async-clarification

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!