Question

I am trying to speed things by having one thread write to a linked list and another thread process the linked list.

For some reason if the method that writes to the linked list I make it into a task and the method that reads from the linked list a low priority thread the program finishes as a whole much faster. In other words I experiense fastests results when doing:

 Task.Factory.StartNew( AddItems );

 new Thread( startProcessingItems ) { Priority = ThreadPriority.Lowest }.Start();

 while(completed==false)
    Thread.Sleep(0);

Maybe because the first task is doing so much extra work than the other thread that's why everything as a whole will finish faster if I set the second method a low priority.

Anyways now my question is The startProcessingItems runs with ThreadPriority = Lowest. How could I change it's priority to highest? If I create a new Task in that method will it be running with low priority? Basically the startProcessingItems ends with a list and once it has that list I will like to start executing with highest priority.

Was it helpful?

Solution

This is not a good approach. First off, LinkedList<T> is not thread safe, so writing to it and reading from it in two threads will cause race conditions.

A better approach would be to use BlockingCollection<T>. This allows you to add items (producer thread) and read items (consumer thread) without worrying about thread safety, as it's completely thread safe.

The reading thread can just call blockingCollection.GetConsumingEnumerable() in a foreach to get the elements, and the write thread just adds them. The reading thread will automatically block, so there's no need to mess with priorities.

When the writing thread is "done", you just call CompleteAdding, which will, in turn, allow the reading thread to finish automatically.

OTHER TIPS

You can improve the performance of your program by changing the inherent design, rather than by changing thread/process priorities.

A big part of your problem is that you're doing a busywait:

while(completed==false)
    Thread.Sleep(0);

This results in it consuming lots of CPU cycles for no productive work, and it's why lowering it's priority makes it execute quicker. If you aren't busywaiting then that won't be an issue any more.

As Reed has suggested, BlockingCollection is tailor made for this situation. You can have a producer thread adding items using Add, and a consumer thread using Take knowing that the method will simply block if there are no more items to be removed.

You can also store the Task you create and use Task.Result or Task.Wait to have the main thread wait for the other task to finish (without wasting CPU cycles). (If you are using threads directly you can use Join.)

In addition to what Reed and Servy have said:

Thread priority is relative to the processes priority.

The Windows scheduler takes into account all other threads when it schedules time for threads. Threads with higher priority take time away from other threads which could artificially slow down the rest of the system. It's not like the system has no reason not to give you thread more priority. The priority would only have an effect if something else took the CPU away from it--which happens for a reason. If nothing took the CPU away from the thread, it won't magically run faster with a priority of Highest.

Setting thread priority to Highest is almost always the wrong thing to do.

Likely the overhead of synchronization between the two threads will kill any performance gain you think you might get.

Also, Thread.Sleep(0) only relinquishes time to threads of equal priority and is ready to run--which could lead to thread starvation. http://msdn.microsoft.com/en-us/library/d00bd51t(v=vs.80).aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top