嗨,我有这两个代码块
当我将浏览器导航到一个URL并尝试等待它时,我陷入僵局,我认为=)任何帮助建议都将不胜感激!
我只是在此处添加一些文本,因此我可以发布问题:/对不起
foreach (var davaType in davaTypes)
{
Parallel.ForEach(years, year =>
{
ts.Add(Task.Run(() =>
{
var th = new Thread(async () =>
{
await doWorkAsync(year, davaType, tarafType);
Application.Run();
});
th.IsBackground = true;
th.SetApartmentState(ApartmentState.STA);
th.Start();
}));
});
}
和
public static async Task doWorkAsync(int year, string davaType, string tarafType)
{
using (var browser = new MyBrowser())
{
Console.WriteLine("Im Created Here");
browser.Navigate("some url");
while (!browser.MyLoaded)
{
Console.WriteLine("waiting");
await Task.Delay(10);
}
Console.WriteLine("complete");
browser.Document?.GetElementById("DropDownList1")?.SetAttribute("value", davaType);
browser.Document.GetElementById("DropDownList3")?.SetAttribute("value", tarafType);
browser.Document.GetElementById("DropDownList4")?.SetAttribute("value", year.ToString());
browser.Document.GetElementById("Button1").MyClick();
await browser.WaitPageLoad(10);
Console.WriteLine("Im DoneHere");
}
}
答案 0 :(得分:0)
您可以使用TaskCompletionSource创建一个任务,并在页面加载后等待它。
答案 1 :(得分:0)
您只需要为WinForms创建一个单独的线程。其他线程将由各个浏览器自己创建。您需要做的是处理其DocumentCompleted事件。文档第一次完成时,您输入并提交数据,第二次完成时,您得到结果。当所有浏览器完成后,您退出winforms线程并完成操作。
注意:为了从winforms线程启动机器人,我使用了Idle事件处理程序,只是因为这是我想到的第一个解决方案。您可能会找到更好的方法。
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;
namespace ConsoleBrowsers
{
class Program
{
static void Main(string[] args)
{
string url = "https://your.url.com";
string[] years = { "2001", "2002", "2003"};
string[] davas = { "1", "2", "3" };
string taraf = "1";
int completed = 0, succeeded = 0;
var bots = new List<Bot>();
var started = false;
var startBots = (EventHandler)delegate (object sender, EventArgs b)
{
if (started)
return;
started = true;
foreach (var dava in davas)
foreach (var year in years)
bots.Add(new Bot { Year = year, Dava = dava, Taraf = taraf, Url = url }.Run((bot, result) =>
{
Console.WriteLine($"{result}: {bot.Year}, {bot.Dava}");
succeeded += result ? 1 : 0;
if (++completed == years.Length * davas.Length)
Application.ExitThread();
}));
};
var forms = new Thread((ThreadStart) delegate {
Application.EnableVisualStyles();
Application.Idle += startBots;
Application.Run();
});
forms.SetApartmentState(ApartmentState.STA);
forms.Start();
forms.Join();
Console.WriteLine($"All bots finished, succeeded: {succeeded}, failed:{bots.Count - succeeded}.");
}
}
class Bot
{
public string Url, Dava, Taraf, Year;
public delegate void CompletionCallback(Bot sender, bool result);
WebBrowser browser;
CompletionCallback callback;
bool submitted;
public Bot Run(CompletionCallback callback)
{
this.callback = callback;
browser = new WebBrowser();
browser.ScriptErrorsSuppressed = true;
browser.DocumentCompleted += Browser_DocumentCompleted;
browser.Navigate(Url);
return this;
}
void Browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (browser.ReadyState == WebBrowserReadyState.Complete)
{
if (submitted)
{
callback(this, true);
return;
}
var ok = SetValue("DropDownList1", Dava);
ok &= SetValue("DropDownList3", Taraf);
ok &= SetValue("DropDownList4", Year);
if (ok)
ok &= Click("Button1");
if (!(submitted = ok))
callback(this, false);
}
}
bool SetValue(string id, string value, string name = "value")
{
var e = browser?.Document?.GetElementById(id);
e?.SetAttribute(name, value);
return e != null;
}
bool Click(string id)
{
var element = browser?.Document?.GetElementById(id);
element?.InvokeMember("click");
return element != null;
}
}
}
答案 2 :(得分:0)
我以前曾遇到过此问题,我所采用的解决方案如下;
private void waitTillLoad()
{
WebBrowserReadyState loadStatus = default(WebBrowserReadyState);
int waittime = 100000;
int counter = 0;
while (true)
{
loadStatus = webBrowser1.ReadyState;
Application.DoEvents();
if ((counter > waittime) || (loadStatus == WebBrowserReadyState.Uninitialized) || (loadStatus == WebBrowserReadyState.Loading) || (loadStatus == WebBrowserReadyState.Interactive))
{
break; // TODO: might not be correct. Was : Exit While
}
counter += 1;
}
counter = 0;
while (true)
{
loadStatus = webBrowser1.ReadyState;
Application.DoEvents();
if (loadStatus == WebBrowserReadyState.Complete)
{
break; // TODO: might not be correct. Was : Exit While
}
counter += 1;
}
}