- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个相对简单的方法来等待元素存在并显示。该方法处理为给定 By 返回多个元素的情况(通常我们只希望显示其中一个元素,但无论如何该方法将返回找到的第一个显示元素)。
我遇到的问题是,当页面上(根本)没有匹配的元素时,它花费的时间比指定的 TimeSpan 多*,我不知道为什么。
*我刚刚测试了 30 秒的超时时间,花了 5m 多一点
代码:
/// <summary>
/// Returns the (first) element that is displayed when multiple elements are found on page for the same by
/// </summary>
public static IWebElement FindDisplayedElement(By by, int secondsToWait = 30)
{
WebDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(secondsToWait);
// Wait for an element to exist and also displayed
IWebElement element = null;
bool success = SpinWait.SpinUntil(() =>
{
var collection = WebDriver.FindElements(by);
if (collection.Count <= 0)
return false;
element = collection.ToList().FirstOrDefault(x => x.Displayed == true);
return element != null;
}
, TimeSpan.FromSeconds(secondsToWait));
if (success)
return element;
// if element still not found
throw new NoSuchElementException("Could not find visible element with by: " + by.ToString());
}
你会用这样的东西来调用它:
[Test]
public void FindDisplayedElement()
{
webDriver.Navigate().GoToUrl("https://stackoverflow.com/questions");
var nonExistenetElementBy = By.CssSelector("#custom-header99");
FindDisplayedElement(nonExistenetElementBy , 10);
}
如果您运行测试(超时 10 秒),您会发现实际退出大约需要 100 秒。
最佳答案
那是因为 SpinWait.WaitUntil
大致实现如下:
public static bool SpinUntil(Func<bool> condition, TimeSpan timeout) {
int millisecondsTimeout = (int) timeout.TotalMilliseconds;
long num = 0;
if (millisecondsTimeout != 0 && millisecondsTimeout != -1)
num = Environment.TickCount;
SpinWait spinWait = new SpinWait();
while (!condition())
{
if (millisecondsTimeout == 0)
return false;
spinWait.SpinOnce();
// HERE
if (millisecondsTimeout != -1 && spinWait.NextSpinWillYield && millisecondsTimeout <= (Environment.TickCount - num))
return false;
}
return true;
}
注意上面“HERE”注释下的条件。它只检查超时是否已过期 IF
spinWait.NextSpinWillYield
返回真。这意味着:如果下一次旋转将导致上下文切换并且超时到期 - 放弃并返回。但除此之外 - 甚至不检查超时就继续旋转。
NextSpinWillYield
结果取决于之前的旋转次数。基本上这个构造旋转 X 次(我相信是 10 次),然后开始屈服(将当前线程时间片交给其他线程)。
SpinUntil
内需要很长时间来评估,这完全违背 SpinWait 的设计——它期望条件评估根本不需要时间(并且 SpinWait 实际适用的地方——这是真的)。假设对您的情况进行一次条件评估需要 5 秒。然后,即使超时是 1 秒 - 它会在检查超时之前先旋转 10 次(总共 50 秒)。那是因为 SpinWait 不是为您尝试使用它的目的而设计的。来自
documentation :
System.Threading.SpinWait is a lightweight synchronization type thatyou can use in low-level scenarios to avoid the expensive contextswitches and kernel transitions that are required for kernel events.On multicore computers, when a resource is not expected to be held forlong periods of time, it can be more efficient for a waiting thread tospin in user mode for a few dozen or a few hundred cycles, and thenretry to acquire the resource. If the resource is available afterspinning, then you have saved several thousand cycles. If the resourceis still not available, then you have spent only a few cycles and canstill enter a kernel-based wait. This spinning-then-waitingcombination is sometimes referred to as a two-phase wait operation.
关于c# - SpinWait.SpinUntil 在等待 Selenium 元素存在时花费的时间比超时时间长得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64763173/
我想知道 Threading.Thread.SpinWait 方法和 Threading.SpinWait 结构之间是否有任何区别。 特别是,在应用程序中实现自旋等待的惯用方式是什么: Thread.
MSDN "Thread-Safe Collections .NET Framework 4"状态: "Some of the concurrent collection types use ligh
我在 C# 中有一个轮询循环,需要在 上每 100 微秒轮询一次。平均 (当然,考虑到没有因内核短缺而由Windows进行过多的抢占式线程上下文切换)。 由于没有时间重新安排,Sleep(1) 不会这
阅读时Albahari's Threading in C# ,我注意到“无锁更新”模式在循环结束时使用了 SpinWait: static void LockFreeUpdate (ref T fie
此代码消耗接近零的 CPU(i5 系列) public void SpinWait() { for (int i = 0; i {
来自MSDN并不太清楚其目的。 可以用来模拟密集的CPU计算测试吗? 最佳答案 它用作非常短期的 sleep 调用的替代品。 当您进行多线程锁定时,如果您尝试获取的资源已被锁定,您通常会进入休眠状态并
我们在我们的应用程序中使用任务。在一个类中,我们想要触发在并行任务上运行的更新。调用看起来像: Maintenance.RecievedMessage += new Notif
我有以下代码: while(flag) { Thread.SpinWait(1); } 以下是 SpinWait 的实现在Rotor(sscli20\clr\src\vm\comsynchroni
我需要旋转线程直到出现特定条件。 在 c# 中,我对 SpinWait 有很好的体验。 但是我对 C++ 有点陌生,我不确定与此等效的是什么: SpinWait.SpinUntil(() =>
我有一个相对简单的方法来等待元素存在并显示。该方法处理为给定 By 返回多个元素的情况(通常我们只希望显示其中一个元素,但无论如何该方法将返回找到的第一个显示元素)。 我遇到的问题是,当页面上(根本)
是否有效 SpinWait.SpinUntil(() => myPredicate(), 10000) 超时为 10000 毫秒 或 同样的条件使用Thread.Sleep轮询是否效率更高例如,类似于
我有一个 WinForm 应用程序,它使用 BackGroundWorker 创建 TCP 客户端并将一些数据发送到远程服务器。当套接字完成时关闭连接,BGW 从 DoWork Sub 退出。 在 R
Windows .NET (C++) 通过 YIELD/PAUSE 指令为超线程友好的忙等待提供 SpinWait。 Linux 和 Mac OS X 上的等效功能是什么?如果系统调用不可用,如何在用
我是一名优秀的程序员,十分优秀!