使用GTK#中的后台工作程序访问GUI元素而不会出现非法访问异常

时间:2014-06-07 07:54:54

标签: c# multithreading mono gtk gtk#

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

我现在将该应用程序移植到mono(GTK#)。有什么方法可以使用后台工作程序来访问GUI元素吗?

我尝试通过添加 system.componentmodel 引用来使用后台工作程序。它可以正常工作。 但是在winforms中我必须禁用 checkforillegeal交叉线程异常 来从后台worker访问GUI元素。但是在GTK#中没有选项可以这样做,因为我使用GTK窗口而不是winforms。我在尝试访问GUI元素时遇到非法访问异常,有类似的方法可以克服这个问题。

  

System.AccessViolationException:数据无法计算表达式   因为线程在本机代码中停止。

1 个答案:

答案 0 :(得分:1)

由于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,必须在UI线程上<{1}} 创建