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

Programmers Heaven: C# School

13. Multithreading

Lesson Plan

Today we will learn how to achieve multithreading in C# and .Net. We will start out by looking at what multithreading is and why we need it. Later we will demonstrate how we can implement multithreading in our C# application. Finally, we will learn about the different issues regarding thread synchronization and how C# handles them.

What is Multithreading

Multithreading is a feature provided by the operating system that enables your application to have more than one execution path at the same time. We are all used to Windows' multitasking abilities, which allow us to execute more than one application at the same time. Just right now I am writing the 14th lesson of the Programmers Heaven's C# School in Microsoft Word, listening to my favorite songs in WinAmp and downloading a new song using Internet Download Manager. In a similar manner, we may use multithreading to run different methods of our program at the same time. Multithreading is such a common element of today's programming that it is difficult to find windows applications that don't use it. For example, Microsoft Word takes user input and displays it on the screen in one thread while it continues to check spelling and grammatical mistakes in the second thread, and at the same time the third thread saves the document automatically at regular intervals. In a similar manner, WinAmp plays music in one thread, displays visualizations in the second and takes user input in the third. This is quite different from multitasking as here a single application is doing multiple tasks at the same time, while in multitasking different applications execute at the same time.

Author's Note: When we say two or more applications or threads are running at the same time, we mean that they appear to execute at the same time, e.g. without one waiting for the termination of the other before starting. Technically, no two instructions can execute together at the same time on a single processor system (which most of us use). What the operating system does is divides the processor's execution time amongst the different applications (multitasking) and within an application amongst the different threads (multithreading).

265

Programmers Heaven: C# School

Consider the following small program:

namespace CSharpSchool

{

class Test

{

static void Main()

{

Fun1();

Fun2();

Console.WriteLine("End of Main()");

}

public static void Fun1()

{

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

{

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

}

}

public static void Fun2()

{

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

{

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

}

}

}

}

The output of the program is:

Fun1() writes: 1

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

266

Programmers Heaven: C# School

End of Main()

Press any key to continue

As we can see, the method Fun2() only started its execution when Fun1() had completed its execution. This is because when a method gets called, the execution control transfers to that method, and when the method returns the execution starts from the very next line of the code that called the method, i.e., the program implicitly has only one execution path.

Using multithreading, we can define multiple concurrent execution paths within our program called threads. For example, we can use threads so that the two methods Fun1() and Fun2() may execute without waiting for each other to terminate.

Multithreading in C#

The .Net Framework, and thus C#, provides full support for multiple execution threads in a program. You can add threading functionality to your application by using the System.Threading namespace. A thread in .Net is represented by the System.Threading.Thread class. We can create multiple threads in our program by creating multiple instances (objects) of this class. A thread starts its execution by calling the specified method and terminates when the execution of that method gets completed. We can specify the method name that the thread will call when it starts by passing a delegate of the ThreadStart type in the Thread class constructor. The delegate System.Threading.ThreadStart may reference any method with has the void return type and which takes no arguments.

public delegate void ThreadStart();

For example, we can change our previous application to run the two methods in two different threads like this:

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

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

Here we have created two instances of the Thread class and passed a ThreadStart type delegate in the constructor which references a method in our program. It is important that the method referenced in the Thread class constructor, through the ThreadStart delegate, is parameterless and has the void return type. A thread does not start its execution when its object is created. Rather, we have to start the execution of a thread by calling the Start() method of the Thread class.

firstThread.Start();

secondThread.Start();

Here we have called the Start() method of firstThread, which in turn will call the Fun1() method in a new thread. However this time the execution will not halt until the completion of the Fun1() method, but will immediately continue with the next statement which also starts the execution of Fun2() method in a new thread. Again, the main

267

Programmers Heaven: C# School

thread of our application will not wait for the completion of the Fun2() method and will continue with the following statement. The complete source code for the application is:

using System;

using System.Threading;

namespace CSharpSchool

{

class Test

{

static void Main()

{

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

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

firstThread.Start();

secondThread.Start();

Console.WriteLine("End of Main()");

}

public static void Fun1()

{

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

{

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

}

}

public static void Fun2()

{

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

{

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

}

}

}

}

One possible output of the program is:

End of Main()

Fun1() writes: 1

268

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