我正处于多线程的学习过程中,所以当我在使用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文档吗?
答案 0 :(得分:1)
目前还不是很明显,但问题是您遇到了两个问题 - 他们互动的方式有点令人困惑。
问题1 - 您无法访问UI thread之外的控件。
问题2 - StartNew没有按照您期望的方式bubble up exceptions。 ContinueWith
可能有助于此。
最终结果是看起来,就像调用失败而没有抛出异常一样。
答案 1 :(得分:1)
如果您的代码可以说话,那就是您正在做的事情:
“我是主线程。嘿调度程序,你可以使用池中的线程为我做这项工作吗?”
() => OrderTickets(numberOfTicktes, cbMovieName.Text)
主线程现在是免费的,稍后(或立即)池线程接受这项工作来做这件事并注意到这一点:
cbMovieName.Text
所以它尝试与cbMovieName
进行通信,但是线程(在你的情况下是主线程或UI线程)介入并说:
“嘿池线程,你为什么要在没有问我的情况下与我的一个控件进行通信?走开!!!(当他翻白眼)”
在池线程上抛出异常但没有冒泡。因此,你似乎从来没有打过电话,但上述情况都发生了。
在另一种情况下你有这个:
string movieName = cbMovies.Text;
() => OrderTickets(numberOfTicktes, movieName)
它将起作用,因为池线程不需要任何UI控件。