read consecutive web pages with CefSharp - cefsharp

What should I do to be able read several consecutive pages from a web site? I am working with CefSharp WinForms and my problem is: In the loop I can get the source from the first page, but any other page gives only part of the source.
I use settings:
CefSettings settings = new CefSettings();
settings.CefCommandLineArgs.Add("enable-media-stream", "1");
settings.CefCommandLineArgs.Add("no-proxy-server", "1");
settings.CefCommandLineArgs.Add("disable-web-security", "1");
settings.CefCommandLineArgs.Add("allow-file-access-from-files", "1");
Cef.Initialize(settings);
And use
public static Task LoadPageAsync(this IWebBrowser browser, string address = null)
{
var tcs = new TaskCompletionSource<bool>();
EventHandler<LoadingStateChangedEventArgs> handler = null;
handler = (sender, args) =>
{
//Wait for while page to finish loading not just the first frame
if (!args.IsLoading)
{
browser.LoadingStateChanged -= handler;
tcs.TrySetResult(true);
}
};
browser.LoadingStateChanged += handler;
if (!string.IsNullOrEmpty(address))
{
browser.Load(address);
}
return tcs.Task;
}

Related

Set a job to failed using Hangfire with ASP.NET?

I have an ASP.NET app which sends emails whenever the user signs up in the web site. I'm using hangfire in order to manage the jobs and postal in order to send emails.
It all works great, but here's the thing:
I want the superuser to change how many times the APP can send the email before deleting the job.
Here's my code
public static void WelcomeUser(DBContexts.Notifications not)
{
try{
var viewsPath = Path.GetFullPath(HostingEnvironment.MapPath(#"~/Views/Emails"));
var engines = new ViewEngineCollection();
engines.Add(new FileSystemRazorViewEngine(viewsPath));
Postal.EmailService service = new Postal.EmailService(engines);
WelcomeUserMail welcomeUserMail = new WelcomeUserMail();
welcomeUserMail.To = not.ReceiverEmail;
welcomeUserMail.UserEmail = not.ReceiverEmail;
welcomeUserMail.From = BaseNotification.GetEmailFrom();
service.Send(welcomeUserMail);
}
catch(Exception e)
{
DBContexts.DBModel dbModel = new DBModel();
DBContexts.Notifications notificacionBD = dbModel.Notifications.Find(not.NotificationID);
notificacionBD.Status = false;
notificacionBD.Timestamp = DateTime.Now;
notificacionBD.Error = e.Message;
int numberOfRetriesAllowed = ParameterHelper.getNumberOfRetriesAllowed();
if (notificacionBD.Retries > numberOfRetriesAllowed)
{
//In this case Hangfire won't put this job in the failed section but rather in the processed section.
dbModel.SaveChanges();
}
else
{
notificacionBD.Retries++;
dbModel.SaveChanges();
throw new Exception(e.Message);
}
}
}
Why not just add attributes to handle it automatically?
[AutomaticRetry(Attempts = 10, LogEvents = true, OnAttemptsExceeded = AttemptsExceededAction.Delete)]
public void MyTask(){
//doing stuff
}
Or you could just make your own attribute that mimics the AutommaticRetryAttribute class but you handle it how you want?
https://github.com/HangfireIO/Hangfire/blob/a5761072f18ff4caa80910cda4652970cf52e693/src/Hangfire.Core/AutomaticRetryAttribute.cs

Will increasing my RAM reduce the size of my w3wp.exe in memory

I have a asp.net web site. I have an image being updated via a timer as many times as possible every second with an image the size of 720x576. I control when the image can be updated by initiating the next ashx page call to get my image after the img control has finished loading the previous image (I do this on the 'onload' event).
My w3wp.exe currently stands at 140,000k and it drops to 130,000. Frequently going up and down between these 2 values.
As i am testing with 1 User and as I am on a cheap VPS shared hosting environment my question is when I go Live will the w3wp.exe become uncontrollable or will the fact that by upgrading my server package (mainly increasing RAM) help to keep this all under control n a multi-user environment?
This is my Javascript:
var timer3;
var intervalLive = 50;
function play2() {
if (timer3) window.clearTimeout(timer3);
swapImages3();
}
function setImageSrc3(src) {
_imgLive.src = src;
timer3 = window.setTimeout(swapImages3, intervalLive);
}
function swapImages3() {
var imgCached = new Image();
imgCached.onload = function () {
setImageSrc3(imgCached.src);
};
imgCached.onerror = function () {
setImageSrc3("http://a URL/images/ERROR.jpg");
};
imgCached.onload = function () {
setImageSrc3(imgCached.src);
};
imgCached.src = null;
imgCached.src = 'http://A URL/Cloud/LiveXP.ashx?id=' + new Date().getTime() + '&Alias=' + alias;
}
And this is in my ashx page:
public class Live : IHttpHandler {
DAL dal = new DAL();
static byte[] StandardError = Shared.ERROR;
public void ProcessRequest(HttpContext context)
{
byte[] data = null;
context.Response.ContentType = "image/jpg";
try
{
if (context.Request.QueryString["Alias"] != null)
{
data = Shared.GetFrame(context.Request.QueryString["Alias"].ToString());
context.Response.BinaryWrite(data);
}
}
catch (Exception ex)
{
data = StandardError;
dal.AddError(ex.ToString());
}
finally
{
context.Response.BinaryWrite(data);
}
}
public bool IsReusable {
get {
return true;
}
}
}
thanks

Workflow application.PersistableIdle event not firing

Hi I am new to Windows Workflow. This may be very easy, but I am stuck on this from long.
I have a state machine workflow, in which i have a workflow host class.
Persistence is not working in this code. While debugging pointer never goes to application.persistableIdle event.
I use custom input argument, for which I have set as Serializable.
below is my code of the host class:
static InstanceStore instanceStore;
static AutoResetEvent instanceUnloaded = new AutoResetEvent(false);
static Activity activity = new Activity1();
static Guid id = new Guid();
static int intContractHeaderKey;
static Contract contract = new Contract();
public ContractActivityHost(Guid wfid, Int32 contractHeaderID)
{
SetupInstanceStore();
StartAndUnloadInstance(contractHeaderID);
if (intContractHeaderKey > 0)
{
LoadAndCompleteInstance(id, intContractHeaderKey);
}
}
static void StartAndUnloadInstance(Int32 contractHeaderID)
{
contract = new Contract();
//var objContract = new object();
var input = new Dictionary<string, object>
{
{"TheContract", contract}
};
input.Add("ContractHeaderKey", contractHeaderID);
WorkflowApplication application = new WorkflowApplication(activity, input);
application.InstanceStore = instanceStore;
//returning IdleAction.Unload instructs the WorkflowApplication to persists application state and remove it from memory
application.PersistableIdle = (e) =>
{
return PersistableIdleAction.Unload;
};
application.Unloaded = (e) =>
{
instanceUnloaded.Set();
};
//application.Idle = (e) =>
// {
// //application.Unload();
// instanceUnloaded.Set();
// };
//This call is not required
//Calling persist here captures the application durably before it has been started
application.Persist();
id = application.Id;
application.Run();
instanceUnloaded.WaitOne();
//application.Unload();
//contract = (Contract)objContract;
intContractHeaderKey = contract.ContractID;
}
static void LoadAndCompleteInstance(Guid wfid, Int32 contractHeaderID)
{
//string input = Console.ReadLine();
while (!contract.ContractWFPause)
{
contract.FireContract(contract.ContractID);
WorkflowApplication application = new WorkflowApplication(activity);
application.InstanceStore = instanceStore;
application.Completed = (workflowApplicationCompletedEventArgs) =>
{
//Console.WriteLine("\nWorkflowApplication has Completed in the {0} state.", workflowApplicationCompletedEventArgs.CompletionState);
strWFStatus = "Completed";
};
application.Unloaded = (workflowApplicationEventArgs) =>
{
//Console.WriteLine("WorkflowApplication has Unloaded\n");
strWFStatus = "Unloaded";
instanceUnloaded.Set();
};
application.Load(wfid);
instanceUnloaded.WaitOne();
}
}
private static void SetupInstanceStore()
{
instanceStore =
new SqlWorkflowInstanceStore(#"Data Source=.;Initial Catalog=WorkflowInstanceStore;Integrated Security=True;");
InstanceHandle handle = instanceStore.CreateInstanceHandle();
InstanceView view = instanceStore.Execute(handle, new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(10));
handle.Free();
instanceStore.DefaultInstanceOwner = view.InstanceOwner;
}
I have been trying to resolve this from long time, but not sure where I am missing anything. I have gone through couple of sample applications and changed my code to match the flow and logic, but still it does not work.
After application.persist, record is inserted in [System.Activities.DurableInstancing].[InstancesTable] view.
But debug pointer does not move beyond instanceUnloaded.WaitOne();
it actually goes to idle state. if I uncomment application.idle event, it goes in that event code.
Any help to resolve this would be great.
Thanks.
Please check If you have added the below details
instanceStore = new SqlWorkflowInstanceStore(ConfigurationManager.ConnectionStrings["WFPersistenceDb"].ConnectionString);
StateMachineStateTracker.Promote(this.instanceStore);

Change this from sync to async webrequests

I ahve been diggin the net for some time now, not finding code examples that help me through my problem.. I have looked at example code but I'm still not "getting" it...
I have read up on,
http://msdn.microsoft.com/en-us/library/aa480507.aspx and
http://msdn.microsoft.com/en-us/library/dd781401.aspx
But I cant seem to get it to work..
Im using HTMLAGILITYPACK
Today I make up to 20 webrequests,
After a request has finished, result is added to dictionary, after that a method searches it for the information, if found the code exits if not it makes another webrequest , until it caps at 20. I need to be able to exit all threads async calls when everything is found.
It goes like this
public void FetchAndParseAllPages()
{
PageFetcher fetcher = new PageFetcher();
for (int i = 0; i < _maxSearchDepth; i += _searchIncrement)
{
string keywordNsearch = _keyword + i;
ParseHtmldocuments(fetcher.GetWebpage(keywordNsearch));
//this checks if the information was found or not, if
//found stop exit and add to database
if (GetPostion() != 201)
{ //ADD DATA TO DATABASE
InsertRankingData(DocParser.GetSearchResults(), _theSearchedKeyword);
return;
}
}
}
This is inside the class that fetches the page
public HtmlDocument GetWebpage(string urlToParse)
{
System.Net.ServicePointManager.Expect100Continue = false;
HtmlWeb htmlweb = new HtmlWeb();
htmlweb.PreRequest = new HtmlAgilityPack.HtmlWeb.PreRequestHandler(OnPreRequest);
HtmlDocument htmldoc = htmlweb.Load(#"urlToParse", "38.69.197.71", 45623, "PORXYUSER", "PROXYPASSWORD");
return htmldoc;
}
public bool OnPreRequest(HttpWebRequest request)
{
// request.UserAgent = RandomUseragent();
request.KeepAlive = false;
request.Timeout = 100000;
request.ReadWriteTimeout = 1000000;
request.ProtocolVersion = HttpVersion.Version10;
return true; // ok, go on
}
How can I make this async and make it really quick with threads? Or should i even use threads when doing it async?
Okay I solved it! At least I think so! Execution time went down to around seven seconds. It took me about 30 secs to do that without async.
Here my code for future reference. EDIT I used a console project to test the code. Also I'm using html agilitypack. This is my way of doing it, any tips on how to further optimize this would be cool to see.
public delegate HtmlDocument FetchPageDelegate(string url);
static void Main(string[] args)
{
System.Net.ServicePointManager.DefaultConnectionLimit = 10;
FetchPageDelegate del = new FetchPageDelegate(FetchPage);
List<HtmlDocument> htmllist = new List<HtmlDocument>();
List<IAsyncResult> results = new List<IAsyncResult>();
List<WaitHandle> waitHandles = new List<WaitHandle>();
DateTime start = DateTime.Now;
for(int i = 0; i < 200; i += 10)
{
string url = #"URLSTOPARSE YOU CHANGE IT HERE READ FROM LIST OR ANYTHING";
IAsyncResult result = del.BeginInvoke(url, null, null);
results.Add(result);
waitHandles.Add(result.AsyncWaitHandle);
}
WaitHandle.WaitAll(waitHandles.ToArray());
foreach (IAsyncResult async in results)
{
FetchPageDelegate delle = (async as AsyncResult).AsyncDelegate as FetchPageDelegate;
htmllist.Add(delle.EndInvoke(async));
}
Console.ReadLine();
}
static HtmlDocument FetchPage(string url)
{
HtmlWeb htmlweb = new HtmlWeb();
HtmlDocument htmldoc = htmlweb.Load(url);
return htmldoc;
}

SharePoint Web Part Custom Properties Don't Take Effect Until Page Reload

I am developing a sharepoint 2007 web part that uses custom properties. Here is one:
[Personalizable(PersonalizationScope.User), WebDisplayName("Policy Update List Name")]
[WebDescription("The name of the SharePoint List that records all the policy updates.\n Default value is Policy Updates Record.")]
public string PolicyUpdateLogName
{
get { return _PolicyUpdateLogName == null ? "Policy Updates Record" : _PolicyUpdateLogName; }
set { _PolicyUpdateLogName = value; }
}
The properties work fine except that the changes are not reflected in the web part until you leave the page and navigate back (or just click on the home page link). Simply refreshing the page doesn't work, which makes me think it has something to do with PostBacks.
My current theory is that the ViewState is not loading postback data early enough for the changes to take effect. At the very least, the ViewState is involved somehow with the issue.
Thanks,
Michael
Here is more relevant code:
protected override void CreateChildControls()
{
InitGlobalVariables();
FetchPolicyUpdateLog_SPList();
// This function returns true if the settings are formatted correctly
if (CheckWebPartSettingsIntegrity())
{
InitListBoxControls();
InitLayoutTable();
this.Controls.Add(layoutTable);
LoadPoliciesListBox();
}
base.CreateChildControls();
}
...
protected void InitGlobalVariables()
{
this.Title = "Employee Activity Tracker for " + PolicyUpdateLogName;
policyColumnHeader = new Literal();
confirmedColumnHeader = new Literal();
pendingColumnHeader = new Literal();
employeesForPolicy = new List<SPUser>();
confirmedEmployees = new List<SPUser>();
pendingEmployees = new List<SPUser>();
}
...
// uses the PolicyUpdateLogName custom property to load that List from Sharepoint
private void FetchPolicyUpdateLog_SPList()
{
site = new SPSite(siteURL);
policyUpdateLog_SPList = site.OpenWeb().GetList("/Lists/" + PolicyUpdateLogName);
}
...
protected void InitListBoxControls()
{
// Init ListBoxes
policies_ListBox = new ListBox(); // This box stores the policies from the List we loaded from SharePoint
confirmedEmployees_ListBox = new ListBox();
pendingEmployees_ListBox = new ListBox();
// Postback & ViewState
policies_ListBox.AutoPostBack = true;
policies_ListBox.SelectedIndexChanged += new EventHandler(OnSelectedPolicyChanged);
confirmedEmployees_ListBox.EnableViewState = false;
pendingEmployees_ListBox.EnableViewState = false;
}
...
private void LoadPoliciesListBox()
{
foreach (SPListItem policyUpdate in policyUpdateLog_SPList.Items)
{
// Checking for duplicates before adding.
bool itemExists = false;
foreach (ListItem item in policies_ListBox.Items)
if (item.Text.Equals(policyUpdate.Title))
{
itemExists = true;
break;
}
if (!itemExists)
policies_ListBox.Items.Add(new ListItem(policyUpdate.Title));
}
}
Do some reading up on the Sharepoint web part life cycle. Properties are not updated until the OnPreRender event.

Resources