gpt4 book ai didi

c# - 创建一个从阻塞线程订阅事件的表单

转载 作者:太空宇宙 更新时间:2023-11-03 22:56:53 24 4
gpt4 key购买 nike

所以我必须更新程序以使用更新版本的 Awesomium,特别是 1.7.5

随着更新,Awesomium 现在必须在它自己的线程上运行,而且它是阻塞的。

我可以使用 WebCore.QueueWork() 将工作排队到阻塞线程,这将完成在调用 WebCore.Run() 的线程上传递的操作。我确保给它自己的线程,这样我的应用程序的其余部分就不会阻塞。

该程序过去的运行方式是创建一个工作对象,该对象具有一个使用 WebCore 库实例化 WebView 和 WebSession 的构造函数。然后它创建了一个表单,该表单接受一个工作对象作为参数,允许该表单订阅来自 WebCore 库的事件。

var worker = new Worker();
var debugForm = new PBForm(worker);
debugForm.Show();

worker 构造函数有这行代码,每当 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 线程卡住了。

我的思路是这样的:

  1. 创建工作人员时,在新线程中创建一个表单作为工作人员实例的属性。
  2. 当 WebCore 事件发生时,worker 实例应该能够更新它的 Form。

它正在编译,表单是响应式的,但图片没有更新,我怀疑这与现在处于不同线程中的表单有关。这是我现在拥有的相关代码:

我将此属性添加到 worker 类:

public PBForm2 DebugForm;

我在 WebCore 阻塞线程中实例化工作类:

WebCore.QueueWork(AddWorker);

在 AddWorker 方法中,我创建了一个新线程并运行一个 Form,同时将它附加到 worker 属性:

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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com