Parallel.Invoke 和 Dispatcher.Invoke 之间的死锁

Deadlock between Parallel.Invoke and Dispatcher.Invoke

我对 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 中使用它时,出现异常-

The calling thread cannot access this object because a different thread owns it

所以我根据其他 Whosebug 帖子的建议使用了 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 中。搜索后,我发现了这个 link- Cannot use Dispatcher.Invoke in Parallel.Invoke,这似乎是一个死锁问题。

我知道我可以在单独的变量中分配文本框值并将它们作为参数传递,然后使用 Parallel.Invoke 但是如果我不使用变量会有什么解决方法?

有人可以建议解决此问题的正确方法吗?

没有直接在 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);

Parallel.Invoke 方法阻塞调用线程,直到所有操作完成。如果您从 UI 线程调用 Parallel.Invoke,然后在 Parallel.Invoke 内部使用 Dispatcher.Invoke 尝试调用 UI 线程,您将陷入死锁,因为 Parallel.Invoke 方法将无法完成。可能的解决方案是将 Parallel.Invoke 包装在 Task.Run 中以减轻 UI 线程。