木偶夏普奇怪的行为

时间:2019-09-17 08:15:32

标签: c# async-await static-methods puppeteer-sharp

我正试图在另一个静态方法中调用Browser.NewPageAsync(),但是当我调用它时,被调用的方法就退出了。

    partial class Program
    {
        static Browser Browser;

        static async Task StartBrowser()
        {
            Browser = await Puppeteer.LaunchAsync
               (
                   new LaunchOptions
                   {
                       Headless = true,
                       ExecutablePath = "Chromium\\chrome.exe"
                   }
               );
            Console.WriteLine("Browser launched");
        }

        static void StartScraping(int threads)
        {
            for (int i = 0; i < threads; i++)
            {
                Task.Run(async () =>
                {
                    int ThreadNumber = i;
                    Console.WriteLine("Thread #" + ThreadNumber + " started");
                    Page p = await Browser.NewPageAsync(); //exits here
                    await p.GoToAsync("https://www.google.com");
                    Console.WriteLine("Content:\n" + await p.GetContentAsync());
                });
            }
        }

        static async Task MainAsync()
        {
            await StartBrowser();
            StartScraping(1);
        }

        static void Main(string[] args)
        {
            MainAsync().GetAwaiter().GetResult();
        }
    }

例如:如果我在Browser.NewPageAsync()中呼叫MainAsync(),那么将按预期方式呼叫Browser.NewPageAsync()

2 个答案:

答案 0 :(得分:0)

您正在开始任务,但没有等到完成。您需要全部等待:

    ...
    static void StartScraping(int threads)
    {
        Task.WaitAll(
            Enumerable.Range(0, threads)
            .Select(async ThreadNumber =>
            {
                try
                {
                    Console.WriteLine("Thread #" + ThreadNumber + " started");
                    Page p = await Browser.NewPageAsync(); //exits here
                    await p.GoToAsync("https://www.google.com");
                    Console.WriteLine("Content:\n" + await p.GetContentAsync());
                }
                catch (Exception e)
                {
                    Console.WriteLine("Thread #" + ThreadNumber + " failed. " + e);
                    throw;
                }
            }).ToArray());
    }

    static async Task MainAsync()
    {
        await StartBrowser();
        StartScraping(1);
    }

还请检查以下伪音问题:link。并确保Chromium版本与此处匹配:link

答案 1 :(得分:0)

我找到了解决方案: 如果将在与浏览器实例相同的范围内创建页面,则将按预期方式创建页面,否则Task.Run()将由于NewPageAsync()方法而卡住。

不良行为:

Task[] Tasks = new Task[1];
Browser browser = await Puppeteer.LaunchAsync
(
    new LaunchOptions
    {
        Headless = true,
        ExecutablePath = "Chromium\\chrome.exe"
    }
);
for (int i = 0; i < Tasks.Length; i++)
{
    int ThreadNumber = i;
    Tasks[i] = Task.Run(async () =>
    {
       Page page = await browser.NewPageAsync(); //stucks
    });
}

Task.WaitAll(Tasks);

符合预期:

Task[] Tasks = new Task[1];
for (int i = 0; i < Tasks.Length; i++)
{
    int ThreadNumber = i;
    Tasks[i] = Task.Run(async () =>
    {
       Browser browser = await Puppeteer.LaunchAsync
       (
           new LaunchOptions
           {
                Headless = true,
               ExecutablePath = "Chromium\\chrome.exe"
           }
       );
       Page page = await browser.NewPageAsync(); //creates as expected
    });
}

Task.WaitAll(Tasks);

无论如何,这不是最佳解决方案,因为我必须为异步任务创建浏览器,而不是为所有异步任务使用一个浏览器。希望有人可以解释。 谢谢大家的帮助!

相关问题