无法通过UI控件'值作为Task.Factory.StartNew中方法的参数

时间:2018-03-11 11:49:31

标签: c# wpf multithreading task

我正处于多线程的学习过程中,所以当我在使用Task类时,我会注意到一些奇怪的(对我来说)行为,调用Task.Factory.StartNew方法。我在WPF应用程序中做了一些示例,我只是尝试从按钮单击的Task调用方法,我所做的是:

Task.Factory.StartNew(() => OrderTickets(numberOfTicktes, cbMovieName.Text));

但是从未调用过OrderTickets方法。然后我改变了我的代码:

string movieName = cbMovies.Text;
Task.Factory.StartNew(() => OrderTickets(numberOfTicktes, movieName ));

在此更改后,我的方法" OrderTickets"按照我的预期召唤。我的问题是为什么我不能直接在Task StartNew方法中使用UI控件的值,就像我尝试使用我的组合框一样?我的猜测,这是因为UI控件由UI线程保持,但不太确定。任何人都可以向我解释这里到底发生了什么?你能指点我描述这个的Microsoft文档吗?

2 个答案:

答案 0 :(得分:1)

目前还不是很明显,但问题是您遇到了两个问题 - 他们互动的方式有点令人困惑。

问题1 - 您无法访问UI thread之外的控件。

问题2 - StartNew没有按照您期望的方式bubble up exceptionsContinueWith可能有助于此。

最终结果是看起来,就像调用失败而没有抛出异常一样。

答案 1 :(得分:1)

如果您的代码可以说话,那就是您正在做的事情:

“我是主线程。嘿调度程序,你可以使用池中的线程为我做这项工作吗?”

() => OrderTickets(numberOfTicktes, cbMovieName.Text)

主线程现在是免费的,稍后(或立即)池线程接受这项工作来做这件事并注意到这一点:

cbMovieName.Text

所以它尝试与cbMovieName进行通信,但是线程(在你的情况下是主线程或UI线程)介入并说:

“嘿池线程,你为什么要在没有问我的情况下与我的一个控件进行通信?走开!!!(当他翻白眼)”

在池线程上抛出异常但没有冒泡。因此,你似乎从来没有打过电话,但上述情况都发生了。

在另一种情况下你有这个:

string movieName = cbMovies.Text;
() => OrderTickets(numberOfTicktes, movieName)

它将起作用,因为池线程不需要任何UI控件。