So I have to update a program to use a newer version of Awesomium, specifically 1.7.5
Well with the update Awesomium now has to operate on it's own thread, and it's blocking.
I can queue work to the blocking thread using WebCore.QueueWork() and this will complete the action passed on the thread WebCore.Run() was called. I made sure to give it it's own thread so the rest of my application isn't blocking.
The way the program used to function was by creating a worker object that had a constructor which instantiated a WebView and WebSession using the WebCore library. It then created a form which accepts a worker object as an argument which allows the form to subscribe to events from the WebCore library.
var worker = new Worker();
var debugForm = new PBForm(worker);
debugForm.Show();
The worker constructor has this line of code which calls the function SurfaceIsDirty whenever the view is updated.
((ImageSurface)_view.Surface).Updated += (s, e) => { if (webView_SurfaceIsDirty != null) webView_SurfaceIsDirty(s, e); };
This function is assigned in the form constructor:
this.worker.webView_SurfaceIsDirty = (sender, e) =>
{
ImageSurface buffer = (ImageSurface)this.worker._view.Surface;
pictureBox1.Image = buffer.Image;
};
So the form picture updates whenever the WebView is updated.
This used to be able to run in the WebCore thread but now since the WebCore thread is blocking I can't get this form to work properly on it.
So this is where I'm stuck. I need to run the Form in a separate thread so it doesn't just hang because it's stuck with the WebCore thread which is blocking.
My idea is as follows:
It's compiling, the form is responsive, yet the picture is not updating and I suspect it's related to the form being in a different thread now. Here's the relevant code I have right now:
I added this property to the worker class:
public PBForm2 DebugForm;
I instantiate the worker class in the WebCore blocking thread:
WebCore.QueueWork(AddWorker);
In the AddWorker method I make a new thread and run a Form while attaching it to the worker property:
static void AddWorker()
{
var worker = new Worker();
Workers.Add(worker);
new Thread(() =>
{
worker.DebugForm = new PBForm2(worker.Id);
var debugForm = new PBForm2(worker.Id);
Application.Run(debugForm);
Application.DoEvents();
}).Start();
}
And finally the worker event itself is now:
((ImageSurface)_view.Surface).Updated += (s, e) =>
{
ImageSurface buffer = (ImageSurface)_view.Surface;
DebugForm.pictureBox1.Image = buffer.Image;
DebugForm.pictureBox1.Refresh();
};
It seems very close to working, the form responds to user interaction and the workers are doing their thing and triggering events, but the picture isn't changing in the form. The event is getting hit and the new image is there, I suspect the fact that the form is in a different thread is causing the image on the form to not update.
This was a very long post so if you are reading this thank you for taking the time to get through it all. I'm very much a novice when it comes to threading and any suggestions or links or even what exactly to search up to solve this issue would be greatly appreciated.
I figured it out, after fixing the issue where I was updating the wrong Form object (thanks Troy Mac1ure) I ran into a threading issue where I couldn't access the Form's picturebox from the Awesomium thread.
I solved it using a helper class:
public static class ThreadHelper
{
private delegate void SetPictureCallback(PBForm f, Image image);
private delegate void AppendTextCallback(PBForm f, string text);
public static void SetPicture(PBForm form, Image image)
{
if (form.InvokeRequired)
{
SetPictureCallback d = SetPicture;
form.Invoke(d, form, image);
}
else
{
form.pictureBox1.Image = image;
form.pictureBox1.Refresh();
}
}
public static void AppendText(PBForm form, string text)
{
if (form.InvokeRequired)
{
AppendTextCallback d = AppendText;
form.Invoke(d, form, text);
}
else
{
form.textBox1.Text += text;
form.textBox1.SelectionStart = form.textBox1.TextLength - 1;
form.textBox1.ScrollToCaret();
form.textBox1.ScrollToCaret();
}
}
}
When the event is triggered in the worker thread I call the function to update the Form:
_view.Surface = new ImageSurface();
((ImageSurface)_view.Surface).Updated += (s, e) =>
{
ImageSurface buffer = (ImageSurface)_view.Surface;
ThreadHelper.SetPicture(DebugForm, buffer.Image);
Application.DoEvents();
};
_view.ConsoleMessage += (s, e) =>
ThreadHelper.AppendText(DebugForm, string.Format("{0} : {1} [{2}]\r\n", e.LineNumber, e.Message, e.Source));