Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лаба №1 / books / csharp_ebook.pdf
Скачиваний:
63
Добавлен:
03.03.2016
Размер:
3.69 Mб
Скачать

Programmers Heaven: C# School

Fun1() writes: 2

Fun1() writes: 3

Fun1() writes: 4

Fun1() writes: 5

Fun2() writes: 10

Fun2() writes: 9

Fun2() writes: 8

Fun2() writes: 7

Fun2() writes: 6

Press any key to continue

Why did we say 'one possible output'? The reason is that we can't be sure about the execution sequence of the threads. Thread switching is completely Operating System dependent and may change each time you execute the program. Here what we notice is that the Main() thread ended before the start of any of the other two threads, but after that the two functions seem to be calling in a sequence.

What we might have expected was loop iterations of the two methods coming in a mixed way. So why didn't we get that output? In fact, the methods Fun1() and Fun2() have such short execution times that they get finished even before the switching of the two threads for a single time. If we increase the loop counters of these methods, we may notice the threads in execution.

Thread Functionality

The Thread class provides a number of useful methods and properties to control and manage thread execution.

Static members of the System.Threading.Thread class

The static property CurrentThread gives a reference to the currently executing thread. Another important static member of the Thread class is the Sleep() method. It causes the currently executing thread to pause temporarily for the specified amount of time.

The Thread.Sleep() method takes as an argument the amount of time (in milliseconds) for which we want to pause the thread. For example, we can pause the currently executing thread for 1 second by passing 1000 as an argument to the Thread.Sleep() method.

static void Main()

{

Console.WriteLine("Before Calling the Thread.Sleep() method");

Thread.Sleep(1000); // blocks the currently executing thread (Main thread) for 1 second Console.WriteLine("After Calling the Thread.Sleep() method");

}

269

Programmers Heaven: C# School

When you execute the above program, you will notice a delay of 1 second between the printing of the two lines.

Instance members of the System.Threaing.Thread class

The most commonly used instance members of the thread class are:

Member

Description

Name

A property of string type used to get/set the friendly name of the thread instance.

Priority

A property of type System.Threading.ThreadPriority. This property is use to get/set the value

 

indicating the scheduling priority of the thread. The priority can be any instance of the

 

ThreadPriority enumeration which includes AboveNormal, BelowNormal, Normal, Highest and

 

Lowest.

IsAlive

A Boolean property indicating whether the thread is alive or has been terminated.

ThreadState

A property of type System.Threading.ThreadState. This property is used to get the value

 

containing the state of the thread. The value returned by this property is an instance of the

 

ThreadState enumeration which includes Aborted, AbortRequested, Suspended, Stopped,

 

Unstarted, Running, WaitSleepJoin, etc.

Start()

Starts the execution of the thread.

Abort()

Allows the current thread to stop the execution of a thread permanently. The method throws the

 

ThreadAbortException in the executing thread.

Suspend()

Pauses the execution of a thread temporarily.

Resume()

Resumes the execution of a suspended thread.

Join()

Makes the current thread wait for another thread to finish.

Thread Demonstration Example - Basic Operations

Now we will start to understand the implementation of threads in C#. Consider the following C# Console program:

using System;

using System.Threading;

namespace CSharpSchool

{

class Test

{

static Thread mainThread; static Thread firstThread; static Thread secondThread; static void Main()

{

mainThread = Thread.CurrentThread;

firstThread = new Thread(new ThreadStart(Fun1));

270

Programmers Heaven: C# School

secondThread = new Thread(new ThreadStart(Fun2));

mainThread.Name = "Main Thread"; firstThread.Name = "First Thread"; secondThread.Name = "Second Thread";

ThreadsInfo("Main() before starting the threads");

firstThread.Start();

secondThread.Start();

ThreadsInfo("Main() just before exiting the Main()");

}

public static void ThreadsInfo(string location)

{

Console.WriteLine("\r\nIn {0}", location); Console.WriteLine("Thread Name: {0}, ThreadState: {1}",

mainThread.Name, mainThread.ThreadState); Console.WriteLine("Thread Name: {0}, ThreadState: {1}",

firstThread.Name, firstThread.ThreadState); Console.WriteLine("Thread Name: {0}, ThreadState: {1}\r\n",

secondThread.Name, secondThread.ThreadState);

}

public static void Fun1()

{

for(int i=1; i<=5; i++)

{

Console.WriteLine("Fun1() writes: {0}", i);

Thread.Sleep(100);

}

ThreadsInfo("Fun1()");

}

public static void Fun2()

{

for(int i=10; i>=6; i--)

{

Console.WriteLine("Fun2() writes: {0}", i);

Thread.Sleep(125);

}

271

Programmers Heaven: C# School

ThreadsInfo("Fun2()");

}

}

}

First of all we have defined three static references of type System.Threading.Thread to reference the three threads (main, first and second thread) later in the Main() method:

static Thread mainThread;

static Thread firstThread;

static Thread secondThread;

We have defined a static method called ThreadsInfo() to display the information (name and state) of the three threads. The two methods Fun1() and Fun2() are similar to the previous program and just print 5 numbers. In the loop of these methods we have called the Sleep() method which will make the thread executing the method suspend for the specified amount of time. We have set slightly different times in each the threads' Sleep() methods. After the loop, we have printed the information about all the threads again.

public static void Fun2()

{

for(int i=10; i>=6; i--)

{

Console.WriteLine("Fun2() writes: {0}", i);

Thread.Sleep(125);

}

ThreadsInfo("Fun2()");

}

Inside the Main() method we first instantiated the two thread instances (firstThread and secondThread) by passing to the constructors the references of the Fun1() and Fun2() methods respectively using the ThreadStart delegate. We also made the reference mainThread point to the thread executing the Main() method by using the Thread.CurrentThread property in the Main() method.

static void Main()

{

mainThread = Thread.CurrentThread;

firstThread = new Thread(new ThreadStart(Fun1));

secondThread = new Thread(new ThreadStart(Fun2));

We then set the Name property of these threads to the threads corresponding names.

mainThread.Name = "Main Thread";

272

Programmers Heaven: C# School

firstThread.Name = "First Thread";

secondThread.Name = "Second Thread";

After setting the names, we printed the current state of the three threads by calling the static ThreadsInfo() method, started the two threads and finally called the ThreadsInfo() method just before the end of the Main() method.

ThreadsInfo("Main() before starting the threads");

firstThread.Start();

secondThread.Start();

ThreadsInfo("Main() just before exiting the Main()");

One possible output of the program is:

In Main() before starting the threads

Thread Name: Main Thread, ThreadState: Running

Thread Name: First Thread, ThreadState: Unstarted

Thread Name: Second Thread, ThreadState: Unstarted

In Main() just before exiting the Main()

Thread Name: Main Thread, ThreadState: Running

Thread Name: First Thread, ThreadState: Unstarted

Thread Name: Second Thread, ThreadState: Unstarted

Fun1() writes: 1

Fun2() writes: 10

Fun1() writes: 2

Fun2() writes: 9

Fun1() writes: 3

Fun2() writes: 8

Fun1() writes: 4

Fun2() writes: 7

Fun1() writes: 5

In Fun1()

Thread Name: Main Thread, ThreadState: Background, Stopped, WaitSleepJoin Thread Name: First Thread, ThreadState: Running

Thread Name: Second Thread, ThreadState: WaitSleepJoin

Fun2() writes: 6

273

Соседние файлы в папке books