如何在没有 AsyncEx 库的情况下调用 anglesharp 异步方法?

How to call an anglesharp async method without AsyncEx library?

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

A​​syncContext 是 AsyncEx 库的一部分。

是否可以在没有 AsyncEx 库的情况下做同样的事情?

Is it possible to do the same thing without AsyncEx library?

不在控制台应用程序中。 AsyncContext 的全部要点是允许您等待 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 大小写,而不是驼峰大小写。

确实可以:

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 等)等待工作完成。