c# - 等待循环中的异步方法完成

标签 c# asynchronous

我有一个 C# 程序,它当前从多个站点同步下载数据,之后代码对我下载的数据执行一些操作。我正在尝试移动它以异步进行下载,然后处理我下载的数据。我在这个排序上遇到了一些麻烦。下面是我正在使用的代码的快照:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Started URL downloader");
        UrlDownloader d = new UrlDownloader();
        d.Process();
        Console.WriteLine("Finished URL downloader");

        Console.ReadLine();
    }
}

class UrlDownloader
{
    public void Process()
    {
        List<string> urls = new List<string>() { 
            "http://www.stackoverflow.com", 
            "http://www.microsoft.com", 
            "http://www.apple.com", 
            "http://www.google.com" 
        };

        foreach (var url in urls)
        {
            WebClient Wc = new WebClient();
            Wc.OpenReadCompleted += new OpenReadCompletedEventHandler(DownloadDataAsync);
            Uri varUri = new Uri(url);
            Wc.OpenReadAsync(varUri, url);
        }
    }

    void DownloadDataAsync(object sender, OpenReadCompletedEventArgs e)
    {
        StreamReader k = new StreamReader(e.Result);
        string temp = k.ReadToEnd();
        PrintWebsiteTitle(temp, e.UserState as string);
    }

    void PrintWebsiteTitle(string temp, string source)
    {
        Regex reg = new Regex(@"<title[^>]*>(.*)</title[^>]*>");
        string title = reg.Match(temp).Groups[1].Value;

        Console.WriteLine(new string('*', 10));
        Console.WriteLine("Source: {0}, Title: {1}", source, title);
        Console.WriteLine(new string('*', 10));
    }
}

本质上,我的问题是这样的。我从上面的输出是:

Started URL downloader
Finished URL downloader
"Results of d.Process()"

我想做的是完成 d.Process() 方法,然后返回到我的 Program 类中的“Main”方法。所以,我正在寻找的输出是:

Started URL downloader
"Results of d.Process()"
Finished URL downloader

我的 d.Process() 方法异步运行,但我不知道如何在返回到 Main 方法之前等待所有处理完成。关于如何在 C#4.0 中执行此操作的任何想法?我不确定如何“告诉”我的 Process() 方法等待所有异步事件完成后再返回 Main 方法。

最佳答案

如果您使用的是 .NET>=4.0,则可以使用 TPL

Parallel.ForEach(urls, url =>
{
    WebClient Wc = new WebClient();
    string page = Wc.DownloadString(url);
    PrintWebsiteTitle(page);
 });

我也会使用 HtmlAgilityPack解析页面而不是正则表达式。

void PrintWebsiteTitle(string page)
{
    HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
    doc.LoadHtml(page);
    Console.WriteLine(doc.DocumentNode.Descendants("title").First().InnerText);
}

关于c# - 等待循环中的异步方法完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11475043/

相关文章:

c# - 在 JavaScript 中传递参数

带有命名空间问题的 C# SelectSingleNode

c# - Winforms .Net 简单数据绑定(bind)不起作用

php - 用户名和密码参数的 AFNetworking 异步 POST 请求(Objective-C iOS)

c# - Fluent NHibernate 的长度属性不适用于更新

c# - delphi vs c# post 返回不同的字符串-utf 问题?

javascript - 使用队列处理异步回调

ruby-on-rails - Resque 或 Gearman - 为后台作业选择合适的工具

c# - SocketAsyncEventArgs以及对Socket的混合Async和Sync调用

c# - ASP.NET WebAPI 2 异步过滤器