我正试图在另一个静态方法中调用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()
。
答案 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);
}
答案 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);
无论如何,这不是最佳解决方案,因为我必须为异步任务创建浏览器,而不是为所有异步任务使用一个浏览器。希望有人可以解释。 谢谢大家的帮助!