我遇到了 C# 程序中 WebBrowsing 自动化的问题。我之前使用过 BHO 的代码,它在那里工作。但是在纯 c# 程序中似乎存在某种死锁。我已经指示我的程序单击搜索按钮,然后等待(通过手动重置事件)让 documentcomplete 发出信号。但是现在似乎直到 ManualResetEvent 发出超时信号才处理对搜索按钮的单击。此后,单击并触发 DocumentComplete-Event。
对于该程序的结构: WebBrowser-Control 是 WindowsForm 的一部分。WebBrowser 控件被传递给运行线程的类。该类再次将控制权传递给另一个类,在该类中根据加载的网络浏览器对具体行为进行编程。
所以在代码中是这样的:
线程的设置
_runner = new Thread(runner); _runner.SetApartmentState(ApartmentState.STA); _runner.IsBackground = true; _runner.Start();
Runner-Method的处理
b.placeTipp(workStructure);
PlaceTipp 方法
public void placeTipp(ref OverallTippStructure tipp) { _expectedUrl = String.Empty; _betUrl = String.Empty; _status = BookieStatusType.CHECKLOGIN; while (true) { _mreWaitForAction.Reset(); checkIETab(); switch (_status) { case BookieStatusType.REQUESTWEBSITE: ConsoleWriter.writeToConsole(String.Format("Bookie {0}: Keine IE-Tab vorhanden. Fordere eine an", this.BookieName)); //if (RequestIETabEvent != null) // RequestIETabEvent(this, new EventArgs()); _status = BookieStatusType.NAVIGATETOWEBSITE; _mreWaitForAction.Set(); break; case BookieStatusType.NAVIGATETOWEBSITE: _webBrowser.Navigate(@"http://www.nordicbet.com"); break; case BookieStatusType.CHECKLOGIN: checkLogin(); break; case BookieStatusType.LOGINNEEDED: doLogin(); break; case BookieStatusType.LOGGEDIN: _status = BookieStatusType.SEARCHTIPP; _mreWaitForAction.Set(); break; case BookieStatusType.SEARCHTIPP: searchTipp(tipp); break; case BookieStatusType.NAVTOSB: NavToSB(); break; case BookieStatusType.GETMARKET: getMarket(tipp); break; case BookieStatusType.PLACEBET: placeBet(tipp); break; case BookieStatusType.CONFIRMBET: confirmBet(); break; case BookieStatusType.EXTRACTBETDATA: extractBetId(ref tipp); break; case BookieStatusType.FINISHED: return; } if (!_mreWaitForAction.WaitOne(60000)) { //Sonderüberpüfung be LoginNeeded if (_status == BookieStatusType.LOGINNEEDED) { //checkLogin(); throw new BookieLoginFailedExcpetion(); } //TIMEOUT! ConsoleWriter.writeToConsole(String.Format("Bookie {0}: Timeout bei warten auf nächsten Schritt. Status war {1}", this.BookieName, this._status.ToString())); throw new BookieTimeoutExcpetion(String.Format("Bookie {0}: Timeout bei dem Warten auf Ereignis", this.BookieName)); } } }
发生死锁的 SearchTipp-Method:
private void searchTipp(OverallTippStructure tipp) { if (_webBrowser.InvokeRequired) { _webBrowser.Invoke(new delegatePlaceBet(searchTipp), new object[] { tipp }); } else { ConsoleWriter.writeToConsole(String.Format("Bookie {0}: Suche Tipp {1}", this.BookieName, tipp.BookieMatchName)); _expectedUrl = String.Empty; if (!_webBrowser.Url.ToString().StartsWith("https://www.nordicbet.com/eng/sportsbook")) { ConsoleWriter.writeToConsole(String.Format("Bookie {0}: Nicht auf Sportsbookseite. Navigiere", this.BookieName)); _status = BookieStatusType.NAVTOSB; _mreWaitForAction.Set(); return; } _searchCompleted = false; HtmlDocument doc = _webBrowser.Document; if (doc != null) { mshtml.IHTMLInputElement elemSearch = (mshtml.IHTMLInputElement)doc.GetElementById("query").DomElement; if (elemSearch != null) { Thread.Sleep(Delayer.delay(2000, 10000)); elemSearch.value = tipp.BookieMatchName; mshtml.IHTMLElement elemSearchButton = (mshtml.IHTMLElement)doc.GetElementById("search_button").DomElement; if (elemSearchButton != null) { Thread.Sleep(Delayer.delay(900, 4000)); elemSearchButton.click(); //elemSearchButton.InvokeMember("click"); if (!_mreWaitForAction.WaitOne(10000)) //Here The Deadlock happens { //Now the click event and therefor the search will be executed ConsoleWriter.writeToConsole(String.Format("Bookie {0}: Suche ist auf Timeout gelaufen", this.BookieName)); throw new BookieTimeoutExcpetion(String.Format("Bookie {0}: Suche ist auf Timeout gelaufen", this.BookieName)); } _mreWaitForAction.Reset(); HtmlElement spanResult = doc.GetElementById("total_ocs_count"); while (spanResult == null) { Thread.Sleep(500); spanResult = doc.GetElementById("total_ocs_count"); } int total_ocs_count = 0; if (!Int32.TryParse(spanResult.InnerHtml, out total_ocs_count)) { ConsoleWriter.writeToConsole(String.Format("Bookie {0}: Tip {1} nicht gefunden", this.BookieName, tipp.BookieMatchName)); throw new BookieTippNotFoundExcpetion(String.Format("Bookie {0}: Tip {1} nicht gefunden", this.BookieName, tipp.BookieMatchName)); } if (total_ocs_count <= 0) { ConsoleWriter.writeToConsole(String.Format("Bookie {0}: Tip {1} nicht gefunden", this.BookieName, tipp.BookieMatchName)); throw new BookieTippNotFoundExcpetion(String.Format("Bookie {0}: Tip {1} nicht gefunden", this.BookieName, tipp.BookieMatchName)); } /* else if (total_ocs_count > 1) { throw new BookieMoreThanOneFoundExcpetion(String.Format("Bookie {0}: Tipp {1} nicht eindeutig", this.BookieName, tipp.BookieMatchName)); } */ ConsoleWriter.writeToConsole(String.Format("Bookie {0}: Tip {1} gefunden", this.BookieName, tipp.BookieMatchName)); _status = BookieStatusType.GETMARKET; } } } _mreWaitForAction.Set(); } }
有人知道这里发生了什么吗?
谢谢
光之使者