I had been struggling with making CEF wait until browser was finished.
I'm creating my own macro tool and I just wanted a simple wait.
I will contribute a solution that worked like a charm for me. (but it needs further testing)
Be prepared because it's gonna be a bumpy ride. Here is the code:
- Code: Select all
public bool WaitForBrowser(ChromiumWebBrowser chrome, int timeoutcheckload)
{
bool didload = false;
var frames = chrome.GetBrowser().GetFrameNames();
bool hasmorecontent = false;
int totalsize = 0;
Stopwatch stopWatch = new Stopwatch();
//stopWatch.Start();
bool please_continue = true;
do
{
do
{
IFrame iframe = null;
string contentloading = "";
bool framesuccess = false;
foreach (string frame in frames)
{
iframe = chrome.GetBrowser().GetFrame(frame);
if (iframe != null)
{
framesuccess = true;
var task = iframe.EvaluateScriptAsync(@"document.getElementsByTagName ('html')[0].innerHTML").ContinueWith(x =>
{
var response = x.Result;
if (response.Success)
{
contentloading += response.Result.ToString();
}
});
task.Wait(100);
}
}
SleepMillisec(100);
if (totalsize < contentloading.Length)
{
totalsize = contentloading.Length;
hasmorecontent = true;
stopWatch.Reset();
}
else
{
hasmorecontent = false;
if(!stopWatch.IsRunning)
{
stopWatch.Start();
}
}
} while (hasmorecontent);
TimeSpan ts = stopWatch.Elapsed;
if (ts.TotalMilliseconds > timeoutcheckload)
{
please_continue = false;
didload = true;
stopWatch.Stop();
}
}
while (please_continue);
return didload;
}
Updated and fixed.
What it does is compare the length of all frame html until the length stop increasing. Then wait timeout in case there are more.
Simple as that.
This is my old code that just simply sucks:
- Code: Select all
//public bool WaitForBrowser(ChromiumWebBrowser chrome, int timeoutcheckload)
//{
// try
// {
// bool didload = false;
// using (var waitHandle = new System.Threading.AutoResetEvent(false))
// {
// EventHandler<FrameLoadStartEventArgs> frameloadstart = null;
// EventHandler<LoadingStateChangedEventArgs> loadingHandler = null;
// bool isloading = false;
// frameloadstart = (sender, e) =>
// {
// isloading = true;
// };
// loadingHandler = (sender, e) =>
// {
// try
// {
// if (!e.IsLoading)
// {
// if (chrome != null)
// {
// chrome.LoadingStateChanged -= loadingHandler;
// chrome.FrameLoadStart -= frameloadstart;
// }
// waitHandle.Set();
// isloading = false;
// }
// else
// {
// isloading = true;
// }
// }
// catch (Exception ex)
// {
// }
// };
// chrome.LoadingStateChanged += loadingHandler;
// chrome.FrameLoadStart += frameloadstart;
// waitHandle.WaitOne(timeoutcheckload);
// if (isloading)
// {
// int timeout2 = timeoutcheckload;
// if(timeout2<5000)
// {
// timeout2 = 200000;
// }
// // System.Threading.Thread.Sleep(5000);
// didload = true;
// waitHandle.WaitOne(timeout2);
// }
// else
// {
// chrome.LoadingStateChanged -= loadingHandler;
// chrome.FrameLoadStart -= frameloadstart;
// }
// }
// return didload;
// }
// catch (Exception ex)
// {
// CheckLDM("WaitForBrowser (not a cmd): Exception'" + ex.Message + "' ");
// }
// return false;
//}
I found a part of it online and maybe I did somehting wrong and it works fine if pages load fast but messes up somehow when they are slower.
after adding a waitHandle.close() it just messed things up even more and I decided to just go with it and check if content is loading.
Please let me know if there is something in my function that will kick my behind so to say.
Appreciate your input.