我对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中。在搜索之后,我发现了这个链接- 不能在Dispatcher.Invoke中使用Parallel.Invoke,这似乎是一个死锁问题。
我知道我可以在单独的变量中分配文本框值,并将它们作为参数传递,然后使用Parallel.Invoke,但是如果我不使用这些变量,那么解决方法是什么呢?
有人能提出解决这个问题的正确方法吗?
发布于 2017-10-14 05:44:10
没有直接在WPF上工作,但错误显然是指示性的。由于Parallel.Invoke的每个参数都在线程上执行,所以尝试从这些线程之外的WPF用户界面(例如textPrime.Text)访问值。
long primeP;
string[] arrIDsP = null;
string[] arrNamesP = null;
string[] arrMergedP = null;
string prime = txtPrime.Text;
string filePath1 = txtFilePath1.Text;
string filePath2 = txtFilePath2.Text;
Parallel.Invoke(
() => primeP = this.FindPrimeNumber(Convert.ToInt64(prime)),
() => arrIDsP = this.FetchData(filePath1),
() => arrNamesP = this.FetchData(filePath2));
arrMergedP = this.MergeIDToNameP(arrIDsP, arrNamesP);
发布于 2019-11-10 18:50:43
Parallel.Invoke方法阻塞调用线程,直到所有操作都完成为止。如果从UI线程调用Parallel.Invoke,然后在Parallel.Invoke中使用试图调用UI线程的Dispatcher.Invoke,则会出现死锁,因为Parallel.Invoke方法将无法完成。可能的解决方案是将Parallel.Invoke封装在Task.Run中以释放UI线程。
https://stackoverflow.com/questions/46741051
复制相似问题