我正在尝试学习/了解更多有关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());
}
}
}
答案 0 :(得分:4)
不要在Task
代码中使用async
构造函数,只有在进行异步工作时才使用async
。 GetStringLength
没有异步工作要做,所以它应该是:
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
GetStringLength
上var result = new Task<int>(() =>
{
return pageData.Length;
});
result.Start();
return result;
时,您将永远等待结果。
您可以手动启动任务:
Task.Run
或使用return Task.Run(() =>
{
return pageData.Length;
});
静态方法,它将创建并启动任务:
{{1}}