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

标签 c# multithreading winforms events 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();

工作构造函数有这行代码,每当 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 类中:

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/

相关文章:

c# - 线程和任务调度

c# - 如何查看一个对象是否在 4 个点内

c# - 为什么使用 GMAIL : text/html; is missing when use MailItem in Outlook plugin, GMAIL.COM 的 SMTP 服务器对 header 内容类型 : SMTP. 进行编码?

c - Posix 线程锁定 : waiting forever

c# - 使用通用回调是一种不好的形式吗?

c# - 项目资源和本地资源图片的区别

c# - C# 中的 Directory.GetFiles() 模式匹配

C# 双类型格式化

winforms - 更改系统颜色

winforms - 允许每个项目在 Winforms 组合框(或列表框)中使用多行