所以我必须更新程序以使用更新版本的 Awesomium,特别是 1.7.5
随着更新,Awesomium 现在必须在它自己的线程上运行,并且它是阻塞的。
我可以使用 WebCore.QueueWork() 将工作排队到阻塞线程,这将完成调用 WebCore.Run() 线程上传递的操作。我确保给它自己的线程,这样我的应用程序的其余部分就不会阻塞。
该程序的运行方式是创建一个工作对象,该对象具有一个使用 WebCore 库实例化 WebView 和 WebSession 的构造函数。然后,它创建了一个接受工作对象作为参数的表单,该对象允许表单订阅来自 WebCore 库的事件。
var worker = new Worker();
var debugForm = new PBForm(worker);
debugForm.Show();
工作构造函数有这行代码,每当 View 更新时,它都会调用函数 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 事件发生时,工作线程实例应该能够更新其表单。
它正在编译,表单有响应,但图片没有更新,我怀疑它与现在处于不同线程中的表单有关。这是我现在拥有的相关代码:
我将此属性添加到 worker 类中:
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();
}
最后,worker 事件本身现在是:
((ImageSurface)_view.Surface).Updated += (s, e) =>
{
ImageSurface buffer = (ImageSurface)_view.Surface;
DebugForm.pictureBox1.Image = buffer.Image;
DebugForm.pictureBox1.Refresh();
};
看起来非常接近工作,表单响应用户交互,工作人员正在做他们的事情并触发事件,但表单中的图片没有改变。该事件正在发生并且新图像就在那里,我怀疑表单位于不同线程中这一事实导致表单上的图像无法更新。
这是一篇很长的文章,所以如果您正在阅读本文,感谢您花时间阅读所有内容。当涉及到线程时,我是一个新手,任何建议或链接,甚至到底要搜索什么来解决这个问题,我们将不胜感激。
最佳答案
您正在创建 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();
关于c# - 创建一个从阻塞线程订阅事件的表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44979749/