简体   繁体   English

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

[英]How to call an anglesharp async method without AsyncEx library?

With AngleSharp , to load HTML page and wait until all stylesheets are downloaded (if required) and all scripts are ready to be parser executed, I do this 使用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 is a part of AsyncEx library. AsyncContext是AsyncEx库的一部分。

Is it possible to do the same thing without AsyncEx library? 没有AsyncEx库可以做同样的事情吗?

Is it possible to do the same thing without AsyncEx library? 没有AsyncEx库可以做同样的事情吗?

Not inside a console application. 不在控制台应用程序内。 The whole point of AsyncContext is to allow you to await a method in Main , which itself isn't async (and can't be). AsyncContext是允许你等待Main一个方法,它本身不是异步(也不是)。 The only alternative is to block the task. 唯一的选择是阻止任务。 Additionaly, as @StephanCleary notes, the continuation inside the context will resume on a single thread, instead of an arbitrary thread pool thread. 另外,正如@StephanCleary所指出的,上下文中的延续将在单个线程上恢复,而不是任意线程池线程。

Without it, it would simply be: 没有它,它只会是:

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

There are rare cases when blocking with Task.Wait is ok, this is one of them. 使用Task.Wait进行阻止的情况很少见,这是其中之一。

Side note - Async methods should be marked with the Async postfix, hence you should use LoadAsync . 附注 - 异步方法应使用Async后缀标记,因此您应该使用LoadAsync Also, .NET method naming conventions are Pascal case, not camel case. 此外,.NET方法命名约定是Pascal案例,而不是驼峰案例。

Indeed you can: 你的确可以:

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

This will do exactly the same, the only difference is the readkey is being executed while the DoWork downloads it's data, if this side effect is not an inconvenient then you're good. 这将完全相同,唯一的区别是当DoWork下载它的数据时正在执行readkey,如果这个副作用不是很不方便那么你就是好的。

Else, you can use a sync event (ManualResetEvent, AutoResetEvent, etc) to wait until the work has been done. 否则,您可以使用同步事件(ManualResetEvent,AutoResetEvent等)等待工作完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM