Schweini
Schweini

Reputation: 17

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

I have the following problem:

I want to write a WPF application which needs to do heavy multithreaded computation in the background. Right now I just add Threads to the Threadpool and if the find the right answer I call the Dispatcher.BeginInvoke methode to update the UI. So at times I have more than 1000 Threads in my Threadpool which wait to be excecuted and the UI freezes.

So I think I need a way to be able to have a fast Queue which runs only a fixed number of Threads while keeping one thread for the UI which always is at idle, so the user can still interact with it.

Anyone got an good Idea on how to solve this? Or do I have to implement a ThreadQueue myself which does excactly that?

My Current Code in Pseudo Code:

WPF Aplication

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

BackgrondWorker

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

Upvotes: 0

Views: 112

Answers (1)

JonasH
JonasH

Reputation: 36351

Running a thousand background threads are likely quite inefficient, both due to added memory usage and due to switching overhead.

A simple way to fix it would be to run a parallel loop on a background thread. I.e.

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

This will limit the number of threads used to something more reasonable, and should probably result in better performance. You can also 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

Upvotes: 3

Related Questions