【发布时间】:2023-03-29 12:09:02
【问题描述】:
我有一个 winforms 项目,每当单击按钮时,它都会调用另一个使用 selenium 的类。我正在努力做到这一点,这样我就可以运行 1 - 无论我想运行多少个窗口。所以,我这样做是为了每当单击按钮时,它都会创建一个新线程并调用一个调用另一个类的方法。问题是每当我执行多个窗口时,似乎只有一个窗口在执行操作。所以如果我想要两个窗口来尝试选择一个国家,只有一个会选择一个国家。然而,两个窗口都打开了 url。我真的很困惑如何或为什么会发生这种情况,我在构造函数中初始化了一个新的 webdriver,所以我不明白为什么它似乎没有做任何其他事情。
using System;
using System.Threading;
using System.Windows.Forms;
namespace MRE
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(generate));
t.IsBackground = true;
t.Start();
// if (!InvokeRequired)
// {
// Invoke((Action)generate);
// }
}
private void generate()
{
Class1 generator = new Class1();
generator.start();
}
}
}
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using System;
using System.Threading;
namespace MRE
{
class Class1
{
public static IWebDriver driver;
public static WebDriverWait wait;
public Class1()
{
driver = new ChromeDriver();
wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
}
public void start()
{
try
{
driver.Navigate().GoToUrl("your url");
//Input DOB
SelectElement oSelect = new SelectElement(driver.FindElement(By.Id("capture-country")));
Thread.Sleep(2000);
oSelect.SelectByValue("GBR");
//click
wait.Until(ExpectedConditions.ElementToBeClickable(By.Id("dob-field-inactive"))).Click();
//enter Month
wait.Until(ExpectedConditions.ElementIsVisible(By.Name("dob-month"))).SendKeys("01");
Thread.Sleep(1000);
//enter Day
wait.Until(ExpectedConditions.ElementIsVisible(By.Name("dob-day"))).SendKeys("01");
Thread.Sleep(1000);
//enter Year
wait.Until(ExpectedConditions.ElementIsVisible(By.Name("dob-year"))).SendKeys("2000");
}
catch (WebDriverException e)
{
}
}
}
}
【问题讨论】:
-
您不能从另一个线程更新 GUI 线程。您是否尝试创建多个 GUI 线程(这比仅启动一个新线程要困难得多)?
Application.DoEvents();是一个很大的代码味道,设计是 foobar。请注意,[STAThread](COM 承诺)和Application.Run都用于正确创建初始 WinForms GUI 线程(消息泵等)。 -
嗯,我添加线程的主要原因是为了使它在 Selenium 打开 chrome 时仍然可以使用 GUI。但问题是,当您单击该按钮两次时,它会打开两个 chrome 窗口并将您带到两个窗口上的 URL,但只有一个 chrome 驱动程序会选择该位置,而另一个只会遇到错误。我的问题不在于 GUI。
-
你需要先修复
generateGoogle。它正在访问 GUI 组件。您可以通过编组到 GUI 线程(Invoke、BeginInvoke、InvokeRequired)来使这些线程安全。你还提到了一个错误。有什么错误?另外,由于各种原因,我也不喜欢threader方法。让我重新阅读您的问题,看看是否能找到更好的解决方案。 -
访问 GUI 的线程安全方法是检查
InvokeRequired,如果是这样,则使用Invoke或BeginInvoke来访问 GUI 线程。Invoke将阻塞直到完成,因此您可以从后台谷歌线程中使用它来访问 GUI 元素。这能解决你的问题吗? -
它抛出的错误是元素不可交互。我抓住了它,所以驱动程序不会崩溃,但我知道它是可交互的,因为另一个 chrome 窗口能够与选择项交互。我也试图更多地理解线程。听起来我正在使用的当前线程方法主要是面向 GUI 的线程?感谢您的帮助。
标签: c# multithreading winforms selenium google-chrome