在gtk#中使用后台worker访问GUI元素而没有非法访问异常

本文关键字:访问 元素 异常 非法 GUI 后台 worker gtk# | 更新日期: 2023-09-27 18:07:42

我有一段相当长的代码,放在后台工作器的Dowork()中。当事情需要完成时,我只是调用runworkerasync()

我现在将该应用程序移植到mono(gtk#)。是否有任何方法可以使用后台工作器访问GUI元素?

我尝试通过添加system.componentmodel引用来使用后台工作器。它的工作原理。但是在winforms中,我必须禁用检查非法的跨线程异常才能从后台worker访问GUI元素。但是在gtk#中没有这样做的选项,因为我使用GTK窗口而不是winforms。当我试图访问GUI元素时,我得到一个非法访问异常,是否有类似的方法来解决这个问题。

系统。AccessViolationException: Data Cannot evaluate expression因为线程是在本机代码中停止的。

在gtk#中使用后台worker访问GUI元素而没有非法访问异常

自Mono 2.4以来,支持Task Parallel Library,这是ThreadPool的抽象和执行后台线程的推荐方式。Mono 3.2.3还支持async/await关键字,它与TPL单独使用很好。

下面是一个非常简单的例子:

Task<int> task = Task.Run( () =>
    {
        int result = 1 + 2;
    }).ContinueWith((task) => 
    {
        // Update GUI Here
    }, TaskScheduler.FromCurrentSynchronizationContext());

这将把计算卸载到ThreadPool线程,并最终将结果返回给Task.Result属性。

如果你想使用BackgroundWorker,你可以注册到RunWorkerCompleted事件并在那里更新你的UserControl

var backgroundWorker = new BackgroundWorker;
backgroundWorker.DoWork += DoWorkMethod
backgroundWorker.RunWorkerCompleted += OnWorkerFinished // Update UI here.
注意,为了在UI线程上调用RunWorkerCompleted, BackgroundWorker必须在UI线程上创建 !