Die Aufgabe wird nicht zum zweiten Mal abgeschlossen. [Zeitweiliges Problem] - Async / Await
Ich habe einWebBrowser
Steuerung ist Windows Forms-Projekt. Es navigiert durch alle in "MyTableTest.html" verfügbaren URLs. Auf dieser Seite befinden sich vier URLs, die vom Webbrowser nacheinander durchsucht werden. Sobald es das letzte erreicht hat, sollte es wieder zum ersten gehen. In der ersten Iteration funktioniert es einwandfrei - in der zweiten Iteration wird es jedoch nicht zu den URLs weitergeleitet. Dies ist ein zeitweiliges Problem - manchmal funktioniert es.
Es scheint (aus dem Protokoll), dass er erwartete Aufgabe nicht abgeschlossen ist. Was kann getan werden, damit es auch in der zweiten Iteration funktioniert?
Hinweis: MyTableTest.html ist unten angegeben
Hinweis: Dies basiert auf dem BeitragHolen Sie sich ReadyState vom WebBrowser-Steuerelement ohne DoEvents
Problem
startNavigation();
WriteLogFunction("Location 1");
// wait for DOM onload event, throw if cancelled
await onloadTcs.Task;
//ISSUE: Not reaching this location at second time navigation
WriteLogFunction("Location 2");
Code
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Load += MainForm_Load;
}
List<string> visitedProducts = new List<string>();
string nextNavigationUrl = String.Empty;
// Form Load event handler
async void MainForm_Load(object sender, EventArgs e)
{
// cancel the whole operation in 20 sec
var cts = new CancellationTokenSource(20000);
//urlStore.Add(@"C:\Samples_L\MyTableTest.html");
nextNavigationUrl = GetHomoePageUrl();
await NavigateInLoopAsync(cts.Token);
}
// navigate to each URL in a loop
async Task NavigateInLoopAsync(CancellationToken ct)
{
bool isIterationComplete = false;
while (!isIterationComplete)
{
string url = String.Empty;
if (String.IsNullOrEmpty(nextNavigationUrl))
{
WriteLogFunction("Close");
isIterationComplete = true;
}
else
{
url = nextNavigationUrl;
ct.ThrowIfCancellationRequested();
WriteLogFunction("Calling NavigateAsync");
Action startNavigation = () => this.webBrowser1.Navigate(url);
var html = await NavigateAsync(ct, startNavigation);
}
}
}
// asynchronous navigation
async Task<string> NavigateAsync(CancellationToken ct, Action startNavigation)
{
var onloadTcs = new TaskCompletionSource<bool>();
EventHandler onloadEventHandler = null;
WriteLogFunction("Inside Function NavigateAsync");
WebBrowserDocumentCompletedEventHandler documentCompletedHandler = delegate
{
// DocumentCompleted may be called several time for the same page,
// if the page has frames
if (onloadEventHandler != null)
return;
// so, observe DOM onload event to make sure the document is fully loaded
onloadEventHandler = (s, e) =>
onloadTcs.TrySetResult(true);
this.webBrowser1.Document.Window.AttachEventHandler("onload", onloadEventHandler);
};
this.webBrowser1.DocumentCompleted += documentCompletedHandler;
try
{
using (ct.Register(() => onloadTcs.TrySetCanceled(), useSynchronizationContext: true))
{
startNavigation();
WriteLogFunction("Location 1");
// wait for DOM onload event, throw if cancelled
await onloadTcs.Task;
//ISSUE: Not reaching this location at second time navigation
WriteLogFunction("Location 2");
}
}
finally
{
this.webBrowser1.DocumentCompleted -= documentCompletedHandler;
if (onloadEventHandler != null)
this.webBrowser1.Document.Window.DetachEventHandler("onload", onloadEventHandler);
}
WriteLogFunction("Place 3");
// the page has fully loaded by now
// optional: let the page run its dynamic AJAX code,
// we might add another timeout for this loop
do { await Task.Delay(500, ct); }
while (this.webBrowser1.IsBusy);
//Call Processing -- Added By Lijo
ExerciseApp(this.webBrowser1, null);
// return the page's HTML content
return this.webBrowser1.Document.GetElementsByTagName("html")[0].OuterHtml;
}
private void ExerciseApp(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WriteLogFunction("ExerciseApp");
var wb = sender as WebBrowser;
int catalogElementIterationCounter = 0;
var elementsToConsider = wb.Document.All;
string productUrl = String.Empty;
bool isClicked = false;
foreach (HtmlElement e1 in elementsToConsider)
{
catalogElementIterationCounter++;
string x = e1.TagName;
String idStr = e1.GetAttribute("id");
if (!String.IsNullOrWhiteSpace(idStr))
{
//Each Product Navigation
if (idStr.Contains("catalogEntry_img"))
{
productUrl = e1.GetAttribute("href");
if (!visitedProducts.Contains(productUrl))
{
WriteLogFunction("productUrl -- " + productUrl);
visitedProducts.Add(productUrl);
isClicked = true;
//e1.InvokeMember("Click");
nextNavigationUrl = productUrl;
break;
}
}
}
}
WriteLogFunction(visitedProducts.Count.ToString());
WriteLogFunction(nextNavigationUrl);
if (visitedProducts.Count == 4)
{
WriteLogFunction("Condition B");
visitedProducts = new List<string>();
}
if (!isClicked)
{
WriteLogFunction("Condition C");
nextNavigationUrl = GetHomoePageUrl();
}
}
private void HomoePageNavigate()
{
webBrowser1.Navigate(GetHomoePageUrl());
}
private string GetHomoePageUrl()
{
return @"C:\Samples_L\MyTableTest.html";
}
private void WriteLogFunction(string strMessage)
{
using (StreamWriter w = File.AppendText("log.txt"))
{
w.WriteLine("\r\n{0} ..... {1} ", DateTime.Now.ToLongTimeString(), strMessage);
}
}
}
MyTableTest.html
<html>
<head>
<style type="text/css">
table {
border: 2px solid blue;
}
td {
border: 1px solid teal;
}
</style>
</head>
<body>
<ta,ble id="four-grid">
<tr>
<td>
<a href="https://www.wikipedia.org/" id="catalogEntry_img63666">
<img src="ssss"
alt="B" width="70" />
</a>
</td>
<td>
<a href="http://www.keralatourism.org/" id="catalogEntry_img63667">
<img src="ssss"
alt="A" width="70" />
</a>
</td>
</tr>
<tr>
<td>
<a href="https://stackoverflow.com/users/696627/lijo" id="catalogEntry_img63664">
<img src="ssss"
alt="G" width="70" />
</a>
</td>
<td>
<a href="http://msdn.microsoft.com/en-US/#fbid=zgGLygxrE84" id="catalogEntry_img63665">
<img src="ssss"
alt="Y" width="70" />
</a>
</td>
</tr>
</table>
</body>
</html>