与更新Awesomium现在有它自己的线程操作创建订阅了事件从阻塞线程
所以我必须更新程序使用Awesomium较新版本的形式,特别是1.7.5与更新Awesomium现在有它自己的线程操作创建订阅了事件从阻塞线程
好,而且它阻塞了。
我可以使用WebCore.QueueWork()将工作排队到阻塞线程,这将完成在线程WebCore.Run()被调用时传递的操作。我一定要给它自己的线程,这样我的应用程序的其余部分就不会被阻塞。
程序用于执行功能的方式是创建一个具有构造函数的工作对象,该构造函数使用WebCore库实例化WebView和WebSession。然后它创建一个接受工作对象作为参数的表单,该表单允许表单订阅来自WebCore库的事件。
var worker = new Worker();
var debugForm = new PBForm(worker);
debugForm.Show();
工作人员构造函数有这行代码,每当视图更新时调用函数SurfaceIsDirty。
((ImageSurface)_view.Surface).Updated += (s, e) => { if (webView_SurfaceIsDirty != null) webView_SurfaceIsDirty(s, e); };
此功能分配的形式构造:
this.worker.webView_SurfaceIsDirty = (sender, e) =>
{
ImageSurface buffer = (ImageSurface)this.worker._view.Surface;
pictureBox1.Image = buffer.Image;
};
所以格式的图片更新每当WebView中被更新。
这用于能够在WebCore线程中运行,但现在自从WebCore线程被阻塞后,我无法让此表单正常工作。
所以这就是我卡住的地方。我需要在一个单独的线程中运行表单,因此它不会挂起,因为它阻塞了WebCore线程。
我的想法是:
- 当工人创造了一个新的线程为工人实例的属性创建表单。
- 当发生WebCore事件时,工作者实例应该能够更新它的Form。
它的编译,表单是响应,但图片没有更新,我怀疑它是与现在在不同线程中的窗体有关。下面是相关的代码,我现在所拥有的:
我添加了这个属性工人阶级:
public PBForm2 DebugForm;
我实例在WebCore的阻塞线程工人阶级:
WebCore.QueueWork(AddWorker);
在AddWorker方法我做一个新的线程并运行一个窗体,同时将其附加到工人属性:
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();
}
最后工人事件本身目前是:
((ImageSurface)_view.Surface).Updated += (s, e) =>
{
ImageSurface buffer = (ImageSurface)_view.Surface;
DebugForm.pictureBox1.Image = buffer.Image;
DebugForm.pictureBox1.Refresh();
};
似乎非常接近的工作,形式响应用户交互和工作人员都在做自己的事情,并触发事件,但是画面没有在改变形成。事件正在发生,新的图像在那里,我怀疑窗体是在不同的线程中导致窗体上的图像不能更新。
这是一篇很长的文章,所以如果你正在阅读这篇文章,感谢你花时间来完成这一切。当谈到线程和任何建议或链接时,我是一个非常新手,甚至不知道为了解决这个问题搜索什么,将不胜感激。
我想通了,固定在那里我被更新错误的Form对象(感谢特洛伊Mac1ure)我遇到了一个线程问题,我无法访问的问题后来自Awesomium线程的表单的图片框。
我解决它使用一个辅助类:
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();
}
}
}
当事件发生时的工作线程我调用该函数更新表单触发:
_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));
您正在创建的相同形式2:
worker.DebugForm = new PBForm2(worker.Id);
var debugForm = new PBForm2(worker.Id);
然后加载debugForm,但您的更新正在做DebugForm.picturebox1所以您的更新将不可见。更新将需要完成debugForm.picturebox1,但你应该只有一个创建。
没有看到所有的代码,为什么不只是加载一个工人类或指向另一个?
Application.Run(worker.DebugForm);
Application.DoEvents();
或
worker.DebugForm = new PBForm2(worker.Id);
var debugForm = worker.DebugForm;
Application.Run(debugForm);
Application.DoEvents();
那么这个固定的一个问题,但导致到另一个,我不能从Awesomium线程触发该事件的窗体的pictureBox1。我通过创建一个静态类来调用Form.Invoke函数正确调用窗体的更改。 –