如何在 C# WPF 中为 ui 保留一个计算量大的后台线程 运行

how to run many backgroundthreads whith heavy computation while reserving one for the ui in c# WPF

我有以下问题:

我想编写一个 WPF 应用程序,它需要在后台进行繁重的多线程计算。现在我只是将线程添加到线程池中,如果找到正确的答案,我将调用 Dispatcher.BeginInvoke 方法来更新 UI。所以有时我的线程池中有超过 1000 个线程等待执行并且 UI 冻结。

所以我想我需要一种方法来拥有一个快速队列,该队列仅运行固定数量的线程,同时为始终处于空闲状态的 UI 保留一个线程,因此用户仍然可以与之互动。

有人知道如何解决这个问题吗?还是我必须自己实现一个 ThreadQueue 才能做到这一点?

我当前的伪代码代码:

WPF 应用程序

init(){
    BackgroundWorker.dosomething();
}
updateUI(data){
    Dispatcher.BeginInvoke(()=>{
        UIFrame = data
    })
}

后台工作者

dosomething(){
    for(i = 0; i < 50000; i++){
        ThreadPool.QueueUserWorkItem(dosomethingElse);
    }
}
dosomethingElse(){
    //Heavy computation with data as a result
    if(foundsomthing){
        WPF.updateUI(data);
    }
}

运行 一千个后台线程可能效率很低,这既是由于增加的内存使用量又是由于切换开销。

一个简单的修复方法是 运行 在后台线程上执行并行循环。即

// On UI thread:
var backgroundTask = Task.Run(dosomething);
...
private void dosomething(){
    Parallel.For(0, 50000, dosomethingElse);
}
private void dosomethingElse(int index){
    ...
}

这会将使用的线程数限制在更合理的范围内,并且可能会带来更好的性能。您也可以 limit the max number of threads used to always leave one or more cpu core to do other things, like updating the UI. If the amount of work done in each iteration is small, you can use partitioning to reduce the threading overhead. You might also want to take a look at the DataFlow APIs