ASP.NET - WebBrowser - 让它等待一两秒钟

时间:2013-06-25 09:20:54

标签: c# asp.net multithreading automation browser

我在ASP.NET中使用Web浏览器登录投注网站并下注。

一旦找到团队并提出其点击方法,javascript将使用文本框加载侧框/窗口以输入下注金额。

我试过了:

var stakeTextboxElement = doc.GetElementById("stake");
stakeTextboxElement.Focus();
stakeTextboxElement.InnerText = "3";
webbrowser.navigate("javascript: placeBet();"); //they use javascript

这给我一个错误,我的出价不够高(当它是)。据我所知,它的导航速度太快而且没有将InnerText读成“3”;

我在Windows窗体中完成了相同的场景,而不是设置InnerText,我做

SendKeys.Send("3"); 
webbrowser.navigate("javascript: placeBet();");

相同的错误。但是,如果我添加'Application.DoEvents();'就在导航之前。执行相同操作不适用于InnerText示例。

据我所知,我必须告诉webbrowser继续运行一两秒,以便它在文本框中读取文本。

2 个答案:

答案 0 :(得分:0)

您的问题是使用专为Web服务器上的UI应用程序设计的控件。我认为您需要使用消息循环才能让浏览器“执行操作”,然后在将ASP.NET请求返回到桌面浏览器之前返回给您。

本质上,该技术是基于System.Windows.Forms.ApplicationContext创建一个新的控件类,然后在创建该控件时将ApartmentState设置为STA。然后它本身包含创建WebBrowser控件的逻辑。然后你有:

  • 执行ASP内容的主线程(Page_Load等)
    • 然后使用AutoResetEvent之类的东西来表示线程间的信号
    • 它将AutoResetEvent传递给您创建的派生控件
    • 等待它以防止它在其他一切完成之前返回您的请求
  • 第二个主题,WebBrowser生活
  • 消息循环的第三个线程,执行WebBrowser事件处理,如Navigating事件处理程序和我们的回调函数。这是您Set AutoResetEvent让主线程返回对原始调用者的响应的地方。

然后可以使用System.Windows.Forms.Application.Run(ApplicationContext ctx)创建消息循环,这样就可以避免使用Windows窗体本身来启动Web浏览器。

这真的很复杂,但有人已经这样做了:CodePlex: Using the WebBrowser Control in ASP.NET

Thread.sleep代码

我们现在知道这对您不起作用

尝试使用Thread.Sleep

stakeTextboxElement.InnerText = "3";
System.Threading.Thread.Sleep(3000);
webbrowser.Navigate("javascript: placeBet();"); //they use javascript

带/不带复位事件的定时器

这可能与Thread.Sleep

有相同的问题

如果这不起作用,请在几秒钟后使用Timer安排Navigate来电。

function void DoNavigate(Object stateInfo) {
  AutoResetEvent arev = (AutoResetEvent)stateInfo; // *
  webbrowser.Navigate("javascript: placeBet();"); //they use javascript
  arev.Set(); // *
}

...
stakeTextboxElement.InnerText = "3";
// depending on your scenario you may need to wait for the navigate to happen, so use 
// a reset event for this
AutoResetEvent arev = new AutoResetEvent(false); // *
TimerCallback tcb = DoNavigate;
Timer stateTimer = new Timer(tcb, arev, 3000, Timeout.Infinite);
arev.WaitOne(); // *

Application.DoEvents

这在ASP.NET中并不是真的可用,但如果您使用的是Windows窗体(如果您使用的是Win Forms或ASP.NET,我不清楚您的问题)并且应用程序正在冻结UI,那么您可能需要让它使用Application.DoEvents来执行事件。

答案 1 :(得分:0)

试试这个:

stakeTextboxElement.InnerText = "3";

DateTime dueTime = DateTime.Now.Add(TimeSpan.FromSeconds(2));
while (DateTime.Now < dueTime)
{
    Application.DoEvents();
}

webbrowser.navigate("javascript: placeBet();");

此外,您不应使用脚本未使用的 InnerText 来获取输入的值,而是更新 Value 属性元素。

stakeTextboxElement.Value = "3";