Welcome to MSDN Blogs Sign in | Join | Help

Thread Management In the .NET Micro Framework

Thread Management In the .NET Micro Framework

Igor Grebnev

 

The .NET Micro Framework provides support for multithreading, just as its larger cousins (the .NET Framework and the .NET Compact Framework) do. In today’s article, I’ll be explaining multithreading in the .NET Micro Framework. I’ll show some common techniques for setting and retrieving priorities, scheduling, and suspending their tasks. 

Setting and Retrieving Thread Priorities

In the .NET Micro Framework, always remember that thread priorities are relative to one another. Specifically, your application sets and retrieves a thread’s priority through the Priority property of Thread class. On the current thread, your program retrieves the thread’s priority using Thread.CurrentThread.Priority. When it does, the Thread.CurrentThread.Priority always returns the enumerated value ThreadPriority.Normal, which has an integer value of 2, no matter what the priority actually is. The reason for this is that the current thread’s priority is calculated relative to the priority of the thread that executed the call to retrieve the property. If the calling thread and the thread being tested are the same, the priority is always ThreadPriority.Normal.

Let’s look into this in more detail. Each thread internally has a data member containing a priority number with a range from 0 to 4. A priority of 0 is lowest, a priority of 2 is normal, and a priority of 4 is highest. This value is stored internally in the framework.

Suppose, for example that a managed code application retrieves the priority of a thread named myWorkerThread. The result is calculated as follows:

myWorkerThread.Priority = myWorkerThread.internalPriority – CurrentThread.internalPriority + 2

where the CurrentThread.internalPriority is priority of the thread that makes the call. If the thread checks its own priority, the result is always ThreadPriority.Normal because myWorkerThread.internalPriority and CurrentThread.internalPriority are the same value.

If, instead, your program checks the priority of one thread from another thread, the priority of the thread being checked is always given relative to the calling thread. So if a calling thread with a priority of 2 checks the priority of a thread with a priority of 4, your program gets an answer of 4 (4-2+2).

Similar calculations are applied on setting of thread priority – the priority is set relative to the priority of the thread that makes the call. The internal priority used by the scheduler is calculated as follows:

myWorkerThread.internalPriority = CurrentThread.internalPriority – 2 + myWorkerThread.Priority

As an example, if a thread with Highest priority sets another thread’s priority to Normal, the resulting thread priority will be Highest. This can be disconcerting when you’re not used to it. The simple way to avoid problems with thread priorities is to always assign thread priorities from a thread that has a priority of Normal.

Scheduling Threads with Different Priorities

Assigning priorities to threads affects how those threads are scheduled. Suppose, for instance, you have two threads. If one thread is assigned a priority of Highest and the other is assigned a value of Normal , they get almost equal CPU time - except of at the very beginning of execution.

On the other hand, if there are two threads with the priorities of Highest and Lowest (the integer values 4 and 1, respectively) then the thread with Highest priority gets 2 times more CPU time than the thread with Lowest priority. Basically, the scheduler gives two CPU time slices to go to Highest priority thread followed by one time slice to Lowest priority thread.

Suspending and Stopping a Thread

When pausing a thread’s execution, be aware that calls to the Thread.Suspend method do not stop the thread immediately. After the call, the thread is put into a “suspended” state, but it will continue to execute until its time slice expires.

Consider the following example:

Debug.Print( “Suspending current thread” );

Thread.CurrentThread.Suspend();

Debug.Print( “Current thread executing” );

 

If you look at the debug output of this code, you’ll see that “Current thread executing” is printed immediately after the call to Suspend. The thread continues to run until its time slice expires. That can take up to 20 milliseconds. When the time slice expires, the thread becomes suspended.

If you need to have a thread suspended immediately, you can call Thread.CurrentThread.Sleep and pass it the value 0 in its parameter list. This stops the thread regardless of whether or not its time slice has expired. The following code demonstrates this technique.

Debug.Print( “Suspending current thread” );

Thread.CurrentThread.Suspend();

Thread.CurrentThread.Sleep(0);

Debug.Print( “Current thread executing” );

 

In this case, the execution of a current thread is blocked as soon as the command Sleep(0) is executed. The suspended thread resumes once other thread calls Resume for it.

Weaving It All Together

Although thread management can be a little tricky, understanding the basic techniques presented in this article will go a long way toward simplifying things.

 

Published Wednesday, April 23, 2008 4:46 PM by NETMF Team Bloggers
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

Thursday, April 24, 2008 3:48 AM by Around and About .NET World

# Gestione dei thread nel .NET Micro Framework

Gestione dei thread nel .NET Micro Framework

Thursday, April 24, 2008 4:26 AM by Jan Kučera

# re: Thread Management In the .NET Micro Framework

Hello,

thank you for this important article.

"On the other hand, if there are two threads with the priorities of Highest and Lowest (the integer values 4 and 1, respectively) then the thread with Highest priority gets 2 times more CPU time than the thread with Lowest priority."

Well does it mean that having two threads with priorities Highest and Lowest is the only possibility how to give more execution time to one thread?

I mean Low-Highest is the same as Normal-Normal except the beginning?

Thanks, Jan

Thursday, April 24, 2008 4:28 AM by Jan Kučera

# re: Thread Management In the .NET Micro Framework

(sorry, Lower should be BelowNormal)

Thursday, April 24, 2008 2:07 PM by Igor Grebnev

# re: Thread Management In the .NET Micro Framework

I mean Low-Highest is the same as Normal-Normal except the beginning?

You can test youself. Create 2 threads with desired prioritites, put counter in each, run both threads and print the counter.

We are fixing it for the next release.

Leave a Comment

(required) 
required 
(required) 
 
Page view tracker