3

使用AngleSharp加载 HTML 页面并等待下载所有样式表(如果需要)并且所有脚本都准备好执行解析器,我这样做

    public sealed class WebReader
    {
        private IDocument _ashDocument;

        public async Task Load(string Url)
        {
            var config = Configuration.Default.WithDefaultLoader().WithJavaScript().WithCss();
            var context = BrowsingContext.New(config);
            _ashDocument = await context.OpenAsync(Url);
        }

        public IEnumerable<string> getImage()
        {
            return  _ashDocument.QuerySelectorAll("img").Select(n => n.Attributes["src"].Value);
        }
    }

    static void Main(string[] args)
    {
        WebReader wReader = new WebReader();           
        AsyncContext.Run((Action)(async () =>
        {
            await wReader.Load("http://blogs.msdn.com/b/dotnet/");
        }));
        IEnumerable<string> imageUrls = wReader.getImage();
        foreach (string url in imageUrls)
        {
            Console.WriteLine(url);
        }

        Console.ReadKey();
    }

AsyncContext 是AsyncEx库的一部分。

如果没有 AsyncEx 库,是否可以做同样的事情?

4

2 回答 2

2

如果没有 AsyncEx 库,是否可以做同样的事情?

不在控制台应用程序内。的全部意义AsyncContext在于允许您等待一个方法 in Main,它本身不是异步的(也不能是)。唯一的选择是阻止任务。另外,正如@StephanCleary 所指出的,上下文内的延续将在单个线程上恢复,而不是在任意线程池线程上恢复。

没有它,它只会是:

static void Main(string[] args)
{
    WebReader wReader = new WebReader();           
    wReader.Load("http://blogs.msdn.com/b/dotnet/")).Wait();
    IEnumerable<string> imageUrls = wReader.getImage();
    foreach (string url in imageUrls)
    {
        Console.WriteLine(url);
    }
}

在少数情况下阻塞Task.Wait是可以的,这就是其中之一。

旁注 - 异步方法应该用Async后缀标记,因此你应该使用LoadAsync. 此外,.NET 方法命名约定是 Pascal 大小写,而不是驼峰大小写。

于 2015-12-18T14:39:20.587 回答
-2

事实上,您可以:

static void Main(string[] args)
{
    DoWork();
    Console.ReadKey();
}

static async void DoWork()
{
    WebReader wReader = new WebReader();           
    await wReader.Load("http://blogs.msdn.com/b/dotnet/");
    IEnumerable<string> imageUrls = wReader.getImage();
    foreach (string url in imageUrls)
    {
        Console.WriteLine(url);
    }
}

这将完全一样,唯一的区别是在 DoWork 下载它的数据时正在执行 readkey,如果这个副作用不是不方便,那么你很好。

否则,您可以使用同步事件(ManualResetEvent、AutoResetEvent 等)等到工作完成。

于 2015-12-18T14:39:30.670 回答