【发布时间】:2017-10-14 05:02:30
【问题描述】:
我对 WPF 和并行处理相当陌生。我已经将一个简单的程序从控制台应用程序转换为 WPF。我想并行执行的功能很少。下面的代码在控制台应用程序中运行良好。
long primeP;
string[] arrIDsP = null;
string[] arrNamesP = null;
string[] arrMergedP = null;
Parallel.Invoke(
() => primeP = this.FindPrimeNumber(Convert.ToInt64(txtPrime.Text)),
() => arrIDsP = this.FetchData(@txtFilePath1.Text),
() => arrNamesP = this.FetchData(@txtFilePath2.Text));
arrMergedP = this.MergeIDToNameP(arrIDsP, arrNamesP);
当我在 WPF 中使用它时,我得到了异常-
调用线程无法访问该对象,因为不同的 线程拥有它
所以我根据其他 Stackoverflow 帖子中的建议使用了 Dispather.Invoke-
Parallel.Invoke(
() => primeP = this.FindPrimeNumber(this.Dispatcher.Invoke(() => Convert.ToInt64(txtPrime.Text))),
() => arrIDsP = this.FetchData(this.Dispatcher.Invoke(() => @txtFilePath1.Text)),
() => arrNamesP = this.FetchData(this.Dispatcher.Invoke(() => @txtFilePath2.Text)));
arrMergedP = this.MergeIDToNameP(arrIDsP, arrNamesP);
现在的问题是我的代码无限卡在 Parallel.Invoke 中。经过搜索,我发现了这个链接-Cannot use Dispatcher.Invoke in Parallel.Invoke,这似乎是一个死锁问题。
我知道我可以在单独的变量中分配文本框值并将它们作为参数传递,然后使用 Parallel.Invoke,但是如果我不使用变量,解决方法是什么?
有人可以建议一个正确的方法来解决这个问题吗?
【问题讨论】:
-
唯一正确的方法是远离任何后台线程访问 UI,因为该工作必须在 UI 线程上完成。强制后台线程执行此操作将创建到 UI 线程的上下文切换!不要试图打败系统。
-
以任何适当的方式来解决这个问题,您需要首先将 UI 数据保存到变量中(就像已经回答的那样)。不知道您究竟为什么要避免这样做(相当合理)的事情。
标签: c# wpf multithreading task-parallel-library dispatcher