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

C# 如何在没有AsyncEx库的情况下调用anglesharp异步方法?,c#,async-await,task-parallel-library,task,anglesharp,C#,Async Await,Task Parallel Library,Task,Anglesharp,使用,加载HTML页面并等待所有样式表被下载(如果需要)并且所有脚本都准备好被解析器执行,我这样做 public sealed class WebReader { private IDocument _ashDocument; public async Task Load(string Url) { var config = Configuration.Default.WithDefaultLoader()

使用,加载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();
    }
公共密封类WebReader
{
私人文件;
公共异步任务加载(字符串Url)
{
var config=Configuration.Default.WithDefaultLoader().WithJavaScript().WithCss();
var context=BrowsingContext.New(配置);
_ashDocument=await context.OpenAsync(Url);
}
公共IEnumerable getImage()
{
返回_ashDocument.queryselectoral(“img”).Select(n=>n.Attributes[“src”].Value);
}
}
静态void Main(字符串[]参数)
{
WebReader花环=新WebReader();
AsyncContext.Run((操作)(异步()=>
{
等待花环加载(“http://blogs.msdn.com/b/dotnet/");
}));
IEnumerable imageUrls=花环器.getImage();
foreach(imageUrls中的字符串url)
{
Console.WriteLine(url);
}
Console.ReadKey();
}
AsyncContext是库的一部分

没有AsyncEx库也可以做同样的事情吗

没有AsyncEx库也可以做同样的事情吗

不在控制台应用程序中。
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);
    }
}
static void Main(字符串[]args)
{
WebReader花环=新WebReader();
花环加载(“http://blogs.msdn.com/b/dotnet/)等等();
IEnumerable imageUrls=花环器.getImage();
foreach(imageUrls中的字符串url)
{
Console.WriteLine(url);
}
}
使用
任务阻塞时很少出现这种情况。等待
是可以的,这是其中之一

旁注-异步方法应该用
Async
postfix标记,因此您应该使用
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);
    }
}
static void Main(字符串[]args)
{
销钉();
Console.ReadKey();
}
静态异步void DoWork()
{
WebReader花环=新WebReader();
等待花环加载(“http://blogs.msdn.com/b/dotnet/");
IEnumerable imageUrls=花环器.getImage();
foreach(imageUrls中的字符串url)
{
Console.WriteLine(url);
}
}
这将做完全相同的,唯一的区别是readkey正在执行,而DoWork下载它的数据,如果这个副作用不是一个不方便,那么你是好的


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

为什么需要另一个
异步void
方法
Load
已经返回了一个
任务
,您可以阻止该任务,从而消除了对
控制台的需要。ReadKey
完全用于等待用户输入,在用户按键之前保持程序打开。另外,等待任务通常是一个非常糟糕的主意,如果任务与等待调用者在同一线程上执行,那么如果OP要求在操作仍在运行时杀死console应用程序,则会造成死锁,而不是ok,但我没有看到OP提到这方面的任何内容。关于你的第二点,不,它不会死锁。控制台应用程序使用默认的
ThreadPoolSynchronizationContext
,其中在任意线程池线程上计划继续。这里不会有任何死锁。@LeMoussel是的,是的。请注意,这不是在控制台应用程序以外的任何环境中通常调用异步方法的方式,这是一种异常情况。
AsyncContext
Wait
方法之间的主要区别在于
AsyncContext
将在单个线程上运行所有的continuations(默认情况下)而
等待
(在控制台应用程序中)将在线程池上运行continuations。@StephanCleary我不认为这是个问题。