gpt4 book ai didi

c# - For 循环仅使用 ExecuteScriptAsync 方法运行一次

转载 作者:行者123 更新时间:2023-12-05 03:19:42 28 4
gpt4 key购买 nike

环境是 C# 和 WinForms。我正在尝试运行一个程序,该程序将在已创建的网站中创建图像下载元素。我使用 WebView2 作为浏览器。我将 for 循环更改为 2 次迭代只是为了调试此问题。我可以成功下载 1 张图像,但我的结果在 1 次迭代时达到最大值。谢谢你的帮助!下面是给我问题的代码:

   async void multiplePics (int column) => await webView2.ExecuteScriptAsync("" +
"var downloadElement=document.createElement('a'); " +
"downloadElement.setAttribute('download',''); " +
"downloadElement.href= document.getElementsByClassName('slick-slide slick-cloned')[" + column + "].getElementsByClassName('item')[0].getAttribute('href'); " +
"document.body.appendChild(downloadElement); " +
"downloadElement.click();" +
"downloadElement.remove(); " +
"");


for (int i = 0; i <= 1; i++)
{
Debug.WriteLine(i);
multiplePics( i);
}


尝试过:

async private void button5_Click(object sender, EventArgs e)
{
void multiplePics(int column) {
//webView2.ExecuteScriptAsync( "javascript");
}

for (int i = 0; i <= 1; i++)
{await multiplePics(i);}
}

也尝试过:

private void button5_Click(object sender, EventArgs e)
{
Task<string> multiplePics(int column) {
//return webView2.ExecuteScriptAsync( "javascript");
}

Task.Run( ()=>{ return multiplePics(0);} );
Task.Run( ()=>{ return multiplePics(1);} );
//tried GetAwaiter() along with GetResult() also
}

另一个尝试:

private async void button5_Click(object sender, EventArgs e)
{
//tried public & private async Task multiplePics with no success
//async Task multiplePics had no errors but had the same result
private async Task multiplePics(int column) =>
await webView2.ExecuteScriptAsync("" +
"var downloadElement=document.createElement('a'); " +
"downloadElement.setAttribute('download',''); " +
"downloadElement.href= document.getElementsByClassName('slick-slide slick-cloned')[" + column + "].getElementsByClassName('item')[0].getAttribute('href'); " +
"document.body.appendChild(downloadElement); " +
"downloadElement.click();" +
"downloadElement.remove(); " +
"");

for (int i = 0; i <= 3; i++)
{
await multiplePics(i);
}

}

最佳答案

首先是更新 multiplePics 的签名以返回一个 Task:

private async Task multiplePics (int column) => await webView2.ExecuteScriptAsync(...);

然后,您可以通过在签名中包含 async 来使用事件处理程序中的方法:

// event handlers use async void, not async Task
private async void button5_Click(object sender, EventArgs e)

最后,您现在可以在事件处理程序中使用您的 multiplePics 方法:

private async void button5_Click(object sender, EventArgs e)
{
for (int i = 0; i <= 1; i++)
{
await multiplePics(i);
}
}

但是,鉴于上述循环仅定义为迭代一次两次,更新循环次数;现在假设 3:

private async void button5_Click(object sender, EventArgs e)
{
for (int i = 0; i < 3; i++) // 3 loops
{
await multiplePics(i);
}
}

假设上面的代码现在将连续下载 3 张图像,您最终会希望并行下载它们并且不阻塞 UI。就个人而言,我建议使用 BackgroundWorker ,但这是一个完全不同的问题。

最后,如果上述方法仍然无效,您需要提供更多信息来说明这意味着什么:“但我的结果在 1 次迭代时达到最大值”。

编辑

有关使用 async/await 的更多信息,我建议您至少先查看这些帖子/文章,其中详细介绍了何时返回 Task 以及何时可以接受 void(提示,仅针对事件)。

SO 答案由一位 C# 语言设计者编写:What's the difference between returning void and returning a Task?

async/await 知识最渊博的开发人员之一撰写的 MSDN 文章:Async/Await - Best Practices in Asynchronous Programming

和回答 SO 问题的 MSDN 文章的同一作者:Why exactly is void async bad?

还有几篇其他文章和 SO q/a 将更深入地探讨该主题;对相关关键字进行一些搜索会大有帮助,例如:“async void vs async task”

编辑 #2

根据我的意见,使用直接取自您最新示例的以下代码,但会为结果添加调试写入。

private async void button5_Click(object sender, EventArgs e)
{
for (int i = 0; i < 3; i++)
{
await multiplePics(i);
}
}

private async Task multiplePics(int column)
{
var result = await webView2.ExecuteScriptAsync("" +
"var downloadElement=document.createElement('a'); " +
"downloadElement.setAttribute('download',''); " +
"downloadElement.href=document.getElementsByClassName('slick-slide slick-cloned')[" + column + "].getElementsByClassName('item')[0].getAttribute('href'); " +
"document.body.appendChild(downloadElement); " +
"downloadElement.click();" +
"downloadElement.remove();" +
"");

Debug.WriteLine($"Col {column} result: {result}");
}

关于c# - For 循环仅使用 ExecuteScriptAsync 方法运行一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73377265/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com