我有一段相当长的代码放在后台工作者的Dowork()
中。
当需要完成任务时,我只需调用runworkerasync()
。
我现在将该应用程序移植到mono(GTK#)。有什么方法可以使用后台工作程序来访问GUI元素吗?
我尝试通过添加 system.componentmodel 引用来使用后台工作程序。它可以正常工作。 但是在winforms中我必须禁用 checkforillegeal交叉线程异常 来从后台worker访问GUI元素。但是在GTK#中没有选项可以这样做,因为我使用GTK窗口而不是winforms。我在尝试访问GUI元素时遇到非法访问异常,有类似的方法可以克服这个问题。
System.AccessViolationException:数据无法计算表达式 因为线程在本机代码中停止。
答案 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}} 创建!