Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C# and the NET Platform, Second Edition - Andrew Troelsen.pdf
Скачиваний:
67
Добавлен:
24.05.2014
Размер:
22.43 Mб
Скачать

Spawning Secondary Threads

 

C# and the .NET Platform, Second Edition

 

by Andrew Troelsen

ISBN:1590590554

When you wish toAprcreatess additional threads to carry on some unit of work, you need to interact with the

© 2003 (1200 pages)

Thread class as well as a special threading-related delegate named ThreadStart. The general process is

This comprehensive text starts with a brief overview of the

quite simple. FirstC#andlanguageforemost,andyouthenneedquicklyto createmov satofunctionkey technical(staticandor instance-level) to perform the additional work. Forarchitecturalexample,issuesassumefor the.NETcurrentdevelopersSimpleThreadApp. project defines the following additional static method, which mimics the work seen in Main():

Table of Contents

static void MyThreadProc()

C# and the .NET Platform, Second Edition

{

Introduction

 

 

Console.WriteLine("***** Secondary Thread stats *****");

Part One - Introducing C# and the .NET Platform

 

Thread.CurrentThread.Name = "TheSecondaryThread";

Chapter 1

- The Philosophy of .NET

 

Thread secondaryThread = Thread.CurrentThread;

Chapter 2

- Building C# Applications

 

Console.WriteLine("Name? {0}", secondaryThread.Name);

Part Two - The C# Programming Language

 

Console.WriteLine("Apt state? {0}", secondaryThread.ApartmentState);

Chapter 3

- C# Language Fundamentals

 

Console.WriteLine("Alive? {0}", secondaryThread.IsAlive);

 

Console.WriteLine("Priority? {0}", secondaryThread.Priority);

Chapter 4

- Obj

ct-Or ented Programming with C#

Chapter 5

- Exc

ptions and Object Lifetime

 

Console.WriteLine("State? {0}", secondaryThread.ThreadState);

Chapter Console6 - Interfaces.WriteLine();and Collections

Chapter}

7

- Callback Interfaces, Delegates, and Events

Chapter 8

- Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

Note The target for the ThreadStart delegate cannot take any arguments and must return void.

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Now, within Main(), create a new Thread class and specify a new ThreadStart delegate as a constructor

Part Four - Leveraging the .NET Libraries

parameter (note the lack of parentheses in the constructor when you give the method name). To inform

Chapter 12 - Object Serialization and the .NET RemotingStart()L yer

the CLR that this new thread is ready to run, call the method (but always remember that Start() Chapterdoesn't13actually- BuildingstartatheB tterthread)Window. Starting(Introducinga threadWindowsis a nondeterministicForms) operation under the total control of

Chapterthe CLR14- you- A Bettercan't doPaintinganythingFrameworkto force (GDI+)the CLR to execute your thread. It will do so on its own time and

Chapon itserown15 -terms:Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

[STAThread]

PartstaticFive - WebvoidApplicationsMain(string[]and XML Webargs)Services

Chapter{ 18 - ASP.NET Web Pages and Web Controls

Chapter... 19 - ASP.NET Web Applications

Chapter //20 -StartXML Weba Servicessecondary thread.

Index Thread secondaryThread = new Thread(new ThreadStart(MyThreadProc));

secondaryThread.Start();

List of Figures

}

List of Tables

The output is seen in Figure 10-11.

Figure 10-11: Your first multithreaded application

Chapter 9 - Understanding .NET Assemblies
Part Three - Programming with .NET Assemblies

C# and the .NET Platform, Second Edition

One question that may be on your mind is exactly when a thread terminates. By default, a thread by Andrew Troelsen ISBN:1590590554

terminates as soon as the function used to create it in the ThreadStart delegate has exited.

Apress © 2003 (1200 pages)

This comprehensive text starts with a brief overview of the

ForegroundC#Threadslanguage andandthen quicklyBackgroundmoves to key tecThreadsnic l and

architectural issues for .NET developers.

The CLR assigns a given thread to one of two broad categories:

Table Foregroundof Contentsthreads: Foreground threads have the ability to prevent the current application from

terminating. The CLR will not shut down an application (which is to say, unload the hosting

C# and the .NET Platform, Second Edition

AppDomain) until all foreground threads have ended.

Introduction

Part One - Introducing C# and the .NET Platform

Background threads: Background threads (sometimes called daemon threads) are viewed by the CLR

Chapter 1 - The Philosophy of .NET

as expendable paths of execution, which can be ignored at any point in time (even if it is currently

Chapter 2 - Building C# Applications

laboring over some unit of work). Thus, if all foreground threads have terminated, any and all

Part Two - The C# Programming Language

background threads are automatically killed.

Chapter 3 - C# Language Fundamentals

ChapterIt is important4 - Objectto note-Orientedthat foregroundProgrammingandwithbackgroundC# threads are not synonymous with primary and

Chapterworker5threads- Exceptions. By default,nd Objeveryct threadLif timeyou create via the Thread.Start() method is automatically a Chapterforeground6 - threadInt rfaces. Again,nd thisCollectionsmeans that the AppDomain will not unload until all threads of execution

have completed their units of work. In most cases, this is exactly the behavior you require.

Chapter 7 - Callback Interfaces, Delegates, and Events

Chapter 8 - Advanced C# Type Construction Techniques

For the sake of argument, however, assume that you wish to spawn a secondary thread that should behave as a background thread. Again, this means that the method pointed to by the Thread type (via the

ThreadStart delegate) should be able to halt safely as soon as all foreground threads are done with their

Chapter 10 - Processes, AppDomains, Contexts, and Threads

work. Configuring such a thread is as simple as setting the IsBackground property to true:

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

// Start a new background thread.

Chapter 12 - Object Serialization and the .NET Remoting Layer

Thread secondaryThread = new Thread(new ThreadStart(MyThreadProc));

Chapter 13 - Building a Better Window (Introducing Windows Forms) secondaryThread.Priority = ThreadPriority.Highest;

Chapter 14 - A Better Painting Framework (GDI+) secondaryThread.IsBackground = true;

Chapter 15 - Programming with Windows Forms Controls Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

PartNow,Fiveto -illustrateWeb Applicatthe distinction,ons and XMLassumeWeb Servicthat thesMyThreadProc() method has been updated to print out

Chapter1000 lines18 -toASPthe.NETconsole,Web PagespausingandforWeb5 millisecondsControls between iterations using the Thread.Sleep() method Chapter(more on19 the- ASPThread.NET Web.Sleep()Applicationsmethod later in this chapter):

Chapter 20 - XML Web Services

Indexstatic void MyThreadProc()

List{ of Figures

List of Tables...

for(int i = 0; i < 1000; i ++)

{

Console.WriteLine("Value of i is: {0}", i);

Thread.Sleep(5);

}

}

If you run the application again, you will find that the for loop is only able to print out a tiny fraction of the values, given that the secondary Thread object has been configured as a background thread. Given that the Main() method has spawned a primary foreground thread, as soon as the secondary thread has been started, it is ready for termination.

Now, you are most likely to simply allow all threads used by a given application to remain configured as foreground threads. If this is the case, all threads must finish their work before the AppDomain is unloaded from the hosting process. Nevertheless, marking a thread as a background type can be helpful when the

worker-thread in question is performing noncritical tasks or helper tasks that are no longer needed when

C# and the .NET Platform, Second Edition the main task of the program is over.

by Andrew Troelsen

ISBN:1590590554

Apress © 2003 (1200 pages)

 

The VS .NET Threads Window

This comprehensive text starts with a brief overview of the

C# language and then quickly moves to key technical and

To wrap up our initial investigation of threads, it is worth pointing out that the Visual Studio .NET IDE architectural issues for .NET developers.

provides a Threads window, which can be accessed from the Debug | Windows menu item during a debugging session. As you can see from Figure 10-12, this window allows you to view the set of currently

Tableexecutingof Contentsthreads in your .NET assembly.

C# and the .NET Platform, Second Edition

Part

Chapter

Chapter

Part

Chapter

Figure 10-12: The VS .NET Threads window

Chapter 4 - Object-Oriented Programming with C#

Chapter 5 - Exceptions and Object Lifetime

Chapter 6 - Interfaces and Collections

SOURCE The ThreadStats project is included under the Chapter 10 subdirectory.

Chapter 7 - Callback Interfaces, Delegates, and Events

CODE

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

Part Four - Leveraging the .NET Libraries
Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

A More Elaborate Threading Example

C# and the .NET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

Now that you haveAprseenss ©the2003basic(1200 processpages)

of creating a new thread of execution, we can turn to a more

illustrative example. Create a new console application named SimpleMultiThreadApp. Next, define a

This comprehensive text starts with a brief overview of the helper class that C#supportslanguagea publicand thenmethodquicklynamedovesDoSomeWork():to key technical and

architectural issues for .NET developers.

internal class WorkerClass

{

Table of Contents

public void DoSomeWork()

C# and the .NET Platform, Second Edition

{

Introduction

// Get hash code for this worker thread.

Part One - Introducing C# and the .NET Platform

Console.WriteLine("ID of worker thread is: {0} ",

Chapter 1 - The Philosophy of .NET

Thread.CurrentThread.GetHashCode());

Chapter 2 - Building C# Applications

// Do the work.

Part Two - The C# Programming Language

Console.Write("Worker says: ");

Chapter 3 - C# Language Fundamentals

for(int i = 0; i < 10; i++)

Chapter 4 - Object-Oriented Programming with C#

{

Chapter 5 - Exceptions and ObjectWriteLine(ifetime

Console. + ", ");

Chapter 6 - Interfaces} and Collections

Chapter 7 - CallbackConsoleInterfaces,.WriteLine();Delegates, and Events

Chapter }8 - Advanced C# Type Construction Techniques

Part} Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Now assume the Main() method creates a new instance of WorkerClass. For the primary thread to continue processing its workflow, create and start a new Thread that is configured to execute the DoSomeWork() method of the WorkerClass type:

Chapter

12

- Object Serialization and the .NET Remoting Layer

Chapter

13

- Building a Better Window (Introducing Windows Forms)

Chapterpublic14class- A BetterMainClassPainting Framework (GDI+)

Chapter{

15

- Programming with Windows Forms Controls

Chapter

public static int Main(string[] args)

16

- The System.IO Namespace

Chapter

{

- Data Access with ADO.NET

17

// Get hash code of the current thread.

Part Five - Web Applications and XML Web Services

Console.WriteLine("ID of primary thread is: {0} ",

Chapter 18 - ASP.NET Web Pages and Web Controls

 

Thread.CurrentThread.GetHashCode());

Chapter 19 - ASP.NET Web Applications

 

// Make worker class.

Chapter 20 - XML Web Services

 

WorkerClass w = new WorkerClass();

Index

// Now make (and start) the worker thread.

 

List of Figures Thread workerThread =

List of Tables

new Thread(new ThreadStart(w.DoSomeWork));

 

 

workerThread.Start();

}

return 0;

 

}

 

If you run the application you would find each thread has a unique hash code (which is a good thing, as you should have two separate threads at this point).

Clogging Up the Primary Thread

Currently, our application creates a secondary thread to perform a unit of work (in this case, printing 10 numbers). The problem is the fact that printing 10 numbers takes no time at all, and therefore we are not really able to appreciate the fact that the primary thread is free to continue processing. Let's update the

application to illustrate this very fact. First, let's tweak the WorkerClass to print out 30,000 numbers, to

C# and the .NET Platform, Second Edition account for a more labor-intensive process:

by Andrew Troelsen

ISBN:1590590554

Apress © 2003 (1200 pages)

internal class WorkerClass

This comprehensive text starts with a brief overview of the

{

C# language and then quickly moves to key technical and

public void DoSomeWork()

architectural issues for .NET developers.

{

...

Table of Contents// Do a lot of work.

Console.Write("Worker says: ");

C# and the .NET Platf rm, Second Edition

Introduction for(int i = 0; i < 30000; i++)

{ Console.WriteLine(i + ", "); }

Part One - Introducing C# and the .NET Platform

Console.WriteLine();

Chapter 1 - The Philosophy of .NET

}

Chapter 2 - Building C# Applications

}

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

Chapter 4 - Object-Oriented Programming with C#

Next, update the MainClass such that it launches a Windows Forms message box directly after it creates

Chapter 5 - Exceptions and Object Lifetime

the worker thread (don't forget to set a reference to System.Windows.Forms.dll):

Chapter 6 - Interfaces and Collections

Chapter 7 - Callback Interfaces, Delegates, and Events

public class MainClass

Chapter 8 - Advanced C# Type Construction Techniques

{

Part Three - Programming with .NET Assemblies

public static int Main(string[] args)

Chapter 9 - Understanding .NET Assemblies

{

Chapter 10 - Processes, AppDomains, Contexts, and Threads

// Create worker thread as before.

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

...

Part Four - Leveraging the .NET Libraries

// Now while worker thread is busy,

Chapter 12 - Object Serializationadditionaland he .NET Remoting Layer

// do some work on primary thread.

Chapter 13 - BuildingMessageBoxBetter.WindowShow("I'mntroducingbuzy");Windows Forms)

Chapter 14 - A rBetturner Painting0; Framework (GDI+)

Chapter }15 - Programming with Windows Forms Controls

}

Chapter 16 - The System.IO Namespace Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

If you were to now run the application, you would see that the message box is displayed and can be

Chapter 18 - ASP.NET Web Pages and Web Controls

moved around the desktop while the worker thread is busy pumping numbers to the console (Figure 10-

Chapter 19 - ASP.NET Web Applications

13).

Chapter 20 - XML Web Services

Index

List of

List of

Figure 10-13: Two threads each performing a unit of work

Now, contrast this behavior with what you might find if you had a single-threaded application. Assume the Main() method has been updated with logic that allows the user to enter the number of threads used within the current AppDomain (one or two):

public static int Main(string[] args)

{

Console.Write("Do you want [1] or [2] threads? ");

C# and the .NET Platform, Second Edition string threadCount = Console.ReadLine();

...

by Andrew Troelsen

ISBN:1590590554

 

 

Apress © 2003 (1200 pages)

// Make worker class.

This comprehensive text starts with a brief overview of the

WorkerClass w = new WorkerClass();

C# language and then quickly moves to key technical and

// Only make a new thread if the user said so. architectural issues for .NET developers.

if(threadCount == "2")

{

// Now make the thread.

Table of Contents

Thread workerThread =

C# and the .NET Platform, Second Edition

new Thread(new ThreadStart(w.DoSomeWork));

Introduction

workerThread.Start();

Part One - Introducing C# and the .NET Platform

}

Chapter 1 - The Philosophy of .NET

else // Execute this method on the single thread.

Chapter 2 - Building C# Applications w.DoSomeWork();

Part Two - The C# Programming Language

// Do some additional work.

Chapter 3 - C# Language Fundamentals

MessageBox.Show("I'm buzy");

Chapter 4 - Object-Oriented Programming with C# return 0;

Chapter 5 - Exceptions and Object Lifetime

}

Chapter 6 - Interfaces and Collections

Chapter 7 - Callback Interfaces, Delegates, and Events

As you can guess, if the user enters the value "1" he or she must wait for all 30,000 numbers to be printed

Chapter 8 - Advanced C# Type Construction Techniques

before seeing the message box appear, given that there is only a single thread in the AppDomain.

Part Three - Programming with .NET Assemblies

However, if the user enters "2" he or she is able to interact with the message box while the secondary

Chapter 9 - Understanding .NET Assemblies

thread spins right along.

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

PartPuttingFour - Leveraginga Threadthe .NETtoLibrariSleeps

Chapter 12 - Object Serialization and the .NET Remoting Layer

The static Thread.Sleep() method can be used to currently suspend the current thread for a specified

Chapter 13 - Building a Better Window (Introducing Windows Forms)

amount of time (specified in milliseconds). In particular, you can use this to pause a program. To illustrate,

Chapter 14 - A Better Painting Framework (GDI+)

let's update the WorkerClass again. This time around, the DoSomeWork() method does not print out

Chapter 15 - Programming with Windows Forms Controls

30,000 lines to the console, but 10 lines. The trick is, between each call to Console.WriteLine(), this

Chapter 16 - The System.IO Namespace

worker thread is put to sleep for approximately 2 seconds.

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

internal class WorkerClass

Chapter 18 - ASP.NET Web Pages and Web Controls

{

Chapter 19 - ASP.NET Web Applications

public void DoSomeWork()

Chapter 20 - XML Web Services

{

Index

// Get some information about the worker thread.

List of Figures

Console.WriteLine("ID of worker thread is: { 0} ",

List of Tables

Thread.CurrentThread.GetHashCode());

// Do the work (and take a nap). Console.Write("Worker says: "); for(int i = 0; i < 10; i++)

{

Console.WriteLine(i + ", ");

Thread.Sleep(2000);

}

Console.WriteLine();

}

}

Now run your application a few times and specify both threading options. You will find radically different behaviors based on your choice of thread number.

SOURCE

CODE

C# andThe theSimpleMultiThreadApp.NET Platform, SecondprojectEditionis included under the Chapter 10 subdirectory.

by Andrew Troelsen

ISBN:1590590554

Apress © 2003 (1200 pages)

This comprehensive text starts with a brief overview of the C# language and then quickly moves to key technical and architectural issues for .NET developers.

Table of Contents

C# and the .NET Platform, Second Edition

Introduction

Part One - Introducing C# and the .NET Platform

Chapter 1 - The Philosophy of .NET

Chapter 2 - Building C# Applications

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

Chapter 4 - Object-Oriented Programming with C#

Chapter 5 - Exceptions and Object Lifetime

Chapter 6 - Interfaces and Collections

Chapter 7 - Callback Interfaces, Delegates, and Events

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

ConcurrencyC# andRevisitedthe .NET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

Given this previous example, you might be thinking that threads are the magic bullet you have been

Apress © 2003 (1200 pages)

looking for. Simply create threads for each part of your application and the result will be increased

This comprehensive text starts with a brief overview of the

application performanceC# languageto theanduserthen. Youquicklyalreadymovesknowto thiskey technicalis a loadedandquestion, as the previous statement is not necessarilyarchitecturaltrue. If not usedi suescarefullyfor .NETanddevelopersthoughtfully,. multithreaded programs are slower than single threaded programs.

TableEvenofmoreContentsimportant is the fact that each and every thread in a given AppDomain has direct access to the C#sharednd thedata.NETof thePlatform,applicationSecond. InEditionthe current example, this is not a problem. However, imagine what might

happen if the primary and secondary threads were both modifying a shared point of data. As you know, the

Introduction

thread scheduler will force threads to suspend their work at random. Since this is the case, what if thread

Part One - Introducing C# and the .NET Platform

A is kicked out of the way before it has fully completed its work? Again, thread B is now reading unstable

Chapter 1 - The Philosophy of .NET

data.

Chapter 2 - Building C# Applications

Part Two - The C# Programming Language

To illustrate, let's build another C# console application named MultiThreadSharedData. This application

Chapter 3 - C# Language Fundamentals

also has a class named WorkerClass, which maintains a private System.Int32 that is manipulated by the

Chapter 4 - Object-Oriented Programming with C#

DoSomeWork() helper function. Also notice that this helper function also leverages a for loop to printout

Chapter 5 - Exceptions and Object Lifetime

the value of this private integer, the iterator's value as well as the name of the current thread. Finally, to

Chapter 6 - Interfaces and Collections

simulate additional work, each iteration of this logic places the current thread to sleep for approximately

Chapter 7 - Callback Interfaces, Delquestion:gates, and Events one second. Here is the type in

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

internal class WorkerClass

Chapter 9 - Understanding .NET Assemblies

{

Chapter 10 - Processes, AppDomains, Contexts, and Threads

private int theInt;

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming public void DoSomeWork()

Part Four - Leveraging the .NET Libraries

{

Chapter 12 - Object Serialization and the .NET Remoting Layer

theInt++;

Chapter 13 - Buildingfor(inta Betteri =Window0; (Introducing< 5; i++)Windows Forms)

Chapter 14 - A {Better Painting Framework (GDI+)

Chapter 15 - ProgrammingConsolewith Windows.WriteLine("theInt:Forms Controls {0}, i: {1}, current thread: {2}",

theInt, i, Thread.CurrentThread.Name);

Chapter 16 - The System.IO Namespace

Thread.Sleep(1000);

Chapter 17 - Data Access with ADO.NET

}

Part Five - Web Applications and XML Web Services

}

Chapter 18 - ASP.NET Web Pages and Web Controls

}

Chapter 19 - ASP.NET Web Applications Chapter 20 - XML Web Services

Index

The Main() method is responsible for creating three uniquely named secondary threads of execution, each

List of Figures

of which is making calls to the same instance of the WorkerClass type:

List of Tables

public class MainClass

{

public static int Main(string[] args)

{

// Make the single worker object.

WorkerClass w = new WorkerClass();

//Create and name three secondary threads,

//each of which makes calls to the same shared object.

Thread workerThreadA =

new Thread(new ThreadStart(w.DoSomeWork)); workerThreadA.Name = "A";

Thread workerThreadB =

new Thread(new ThreadStart(w.DoSomeWork)); workerThreadB.Name = "B";

Thread workerThreadC =

new Thread(new ThreadStart(w.DoSomeWork));

C# and the .NET Platform, Second Edition workerThreadC.Name = "C";

by Andrew Troelsen

ISBN:1590590554

// Now start each one.

 

Apress © 2003 (1200 pages)

 

workerThreadA.Start();

 

This comprehensive text starts with a brief overview of the workerThreadB.Start();

C# language and then quickly moves to key technical and workerThreadC.Start();

architectural issues for .NET developers. return 0;

}

}

Table of Contents

C# and the .NET Platform, Second Edition

Introduction

Part One - Introducing C# and the .NET Platform

Now before you see some test runs, let's recap the problem. The primary thread within this AppDomain

Chapter 1 - The Philosophy of .NET

begins life by spawning three secondary worker threads. Each worker thread is told to make calls on the

Chapter 2 - Building C# Applications

DoSomeWork() method of a single WorkerClass instance. Given that we have taken no precautions to PartlockTwodown- ThetheC#object'sProgrammingshared resources,Language there is a good chance that a given thread will be kicked out of Chapterthe way3before- C# theLanguageWorkerClassFundamentalsis able to print out the results for the previous thread. Because we don't

Chapterknow exactly4 - Objectwhen-Oriented(or if) thisProgrammingmight happen,withweC#are bound to get unpredictable results. For example, you

Chaptermight find5 -theExceptionsoutput shownand Objectin FigureLif time10-14.

Chapter 6 - Interfaces and Collections

Chapter

Chapter

Part

Chapter

 

Chapter

 

Chapter

Programming

Part

 

Chapter

 

Chapter

Forms)

Chapter

 

Chapter

 

Chapter

 

Chapter

 

Part

 

Chapter

 

Chapter 19 - ASP.NET Web Applications

Figure 10-14: Possible output of the MultiThreadSharedData application

Chapter 20 - XML Web Services

IndexNow run the application a few more times. Figure 10-15 shows another possibility (note the ordering Listamongof Figuresthread names).

List of Tables

Chapter 6 - Interfaces and Collections
Chapter 5 - Exceptions and Object Lifetime

ISBN:1590590554

overview of the

technical and

Table

C# and

Part

Chapter

Chapter

Part

Figure 10-15: Another possible output of the MultiThreadSharedData application

Chapter 3 - C# Language Fundamentals

Chapter 4 - Object-Oriented Programming with C#

Humm. There are clearly some problems here. As each thread is telling the WorkerClass to "do some work," the thread scheduler is happily swapping threads in the background. The result is inconsistent

output. What we need is a way to programmatically enforce synchronized access to the shared resources.

Chapter 7 - Callback Interfaces, Delegates, and Events

ChapterAs you8would- Advancedguess, theC# SystemT pe Construction.ThreadingTechniquesnamespace provides a number of synchronization-centric

ParttypesThree. The- ProgrammingC# programmingwithlanguage.NET Assembliesalso provides a particular keyword for the very task of synchronizing

Chaptsharedr 9data- Uindersmultandingithreaded.NETapplicationsAssemblies.

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

SynchronizationC# and theUsing.NET Platform,the C#Second"lock"EditionKeyword

by Andrew Troelsen

ISBN:1590590554

The first approach to providing synchronized access to our DoSomeWork() method is to make use of the C#

Apress © 2003 (1200 pages)

"lock" keyword. This intrinsic keyword allows you to lock down a block of code so that incoming threads must

This comprehensive text starts with a brief overview of the

wait in line for theC#currentlanguagethreadndtothenfinishquicklyup itsmoveswork completelyto key technical. Theand"lock" keyword requires you to pass in a token (an object reference)architecturalthatissuesmustforbe.NETacquireddev lopersby a.thread to enter within the scope of the lock statement. When you are attempting to lock down an instance level method, you can simply pass in a reference to the current type:

Table of Contents

C# and the .NET Platform, Second Edition

internal class WorkerClass

Introduction

{

Part One - Introducing C# and the .NET Platform

private int theInt;

Chapter 1 - The Philosophy of .NET

public void DoSomeWork()

Chapter 2 - Building C# Applications

{

Part Two - The C# Programming Language

lock(this)

Chapter 3 - C# Language Fundamentals

{

Chapter 4 - Object-Oriented Programming with C# theInt++;

Chapter 5 - Exceptionsfor(intand Objecti Lifetime= 0; i < 5; i++)

Chapter 6 - Interfaces{and Collections

Chapter 7 - Callback Interfaces,ConsoleDelegates,.WriteLine("theInt:and Events {0}, i: {1}, current thread: {2}"

theInt, i, Thread.CurrentThread.Name);

Chapter 8 - Advanced C# Type Cons ruction Techniques

Thread.Sleep(1000);

Part Three - Programming with .NET Assemblies

}

Chapter 9 - Understanding .NET Assemblies

} // Lock token released here!

Chapter 10 - Processes, AppDomains, Contexts, and Threads

}

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

}

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Now, once a thread enters into a locked block of code, the token (in this case, a reference to the current object

Chapter 14 - A Better Painting Framework (GDI+)

is inaccessible by other threads until the lock is released. Thus, if threadA has obtained the lock token, and

Chapter 15 - Programming with Windows Forms Controls

threadB or threadC are attempting to enter, they must wait until threadA relinquishes the lock.

Chapter 16 - The System.IO Namespace

Note If you are attempting to lock down code in a static method, you obviously cannot use the "this"

Chapter 17 - Data Access with ADO.NET

keyword. If this is the case, you can simply pass in the System.Type of the current class using the C#

Part Five - Web Applications and XML Web Services

"typeof" operator (although any object reference will work).

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

If you now rerun the application, you can see that the threads are instructed to politely wait in line for the curren

Chapter 20 - XML Web Services

thread to finish its business (Figure 10-16).

Index

List of Figures

List of

Figure 10-16: Consistent output of the MultiThreadSharedData application

SOURCE

C# and the .NET Platform, Second Edition

 

The MultiThreadSharedData application is included under the Chapter 10 subdirectory.

 

by Andrew Troelsen

ISBN:1590590554

CODE

Apress © 2003 (1200 pages)

This comprehensive text starts with a brief overview of the

SynchronizationC# languageUsingand thenthequicklySystemmoves to.Threadingkey t chnical and.Monitor Type

architectural issues for .NET developers.

The C# lock statement is really just a shorthand notation for working with the System.Threading.Monitor class type. Under the hood, the previous locking logic (via the C# "lock" keyword) actually resolves to the following

Table of Contents

(which can be verified using ildasm.exe):

C# and the .NET Platform, Second Edition

Introduction

internal class WorkerClass

Part One - Introducing C# and the .NET Platform

{

Chapter 1 - The Philosophy of .NET

private int theInt;

Chapter 2 - Building C# Applications

public void DoSomeWork()

Part Two{- The C# Programming Language

Chapter 3 - C# Language Fundamentals

// Enter the monitor with token.

Chapter 4 - Object-Oriented Programming with C#

Monitor.Enter(this);

Chapter 5 - Exceptionstry and Object Lifetime

Chapter 6 - Interfaces{ and Collections

Chapter 7 - Callback Interfaces,theInt++;Delegates, and Events

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

Chapter 8 - Advanced C# Type Construction Techniques

{

Part Three - Programming with .NET Assemblies

Console.WriteLine("theInt: {0}, i: {1}, current thread: {2}"

Chapter 9 - Understanding .NET Assemblies

theInt, i, Thread.CurrentThread.Name);

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Thread.Sleep(1000);

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

}

Part Four - Leveraging the .NET Libraries

}

Chapter 12 - Object Serialization and the .NET Remoting Layer

finally

Chapter 13 - Building a Better Window (Introducing Windows Forms)

{

Chapter 14 - A Better Painting Framework (GDI+)

// Error or not, you must exit the monitor

Chapter 15 - Programming with Windows Forms Controls

// and release the token.

Chapter 16 - The System.IO Namespace

Monitor.Exit(this);

Chapter 17 - Data Access with ADO.NET

}

Part Five}- Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

}

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

If you run the modified application, you will see no changes in the output (which is good). Here, you make use o

Index

the static Enter() and Exit() members of the Monitor type, to enter (and leave) a locked block of code. Now,

List of Figures

given that the "lock" keyword seems to require less code than making explicit use of the

List of Tables

System.Threading.Monitor type, you may wonder about the benefits. The short answer is control.

If you make use of the Monitor type, you are able to instruct the active thread to wait for some duration of time (via the Wait() method), inform waiting threads when the current thread is completed (via the Pulse() and PulseAll() methods), and so on. As you would expect, in a great number of cases, the C# "lock" keyword will fit the bill. If you are interested in checking out additional members of the Monitor class, consult online Help.

SynchronizationC# and theUsing.NET Platform,the SystemSecond Edition.Threading.Interlocked Type

by Andrew Troelsen

ISBN:1590590554

Although it always is hard to believe until you look at the underlying CLR code, assignments and simple

Apress © 2003 (1200 pages)

arithmetic operations are not atomic. For this reason, the System.Threading namespace also provides a

This comprehensive text starts with a brief overview of the

type that allows youC# tolanguageoperateandonthena singlequicklypointmovesof datato keyatomicallyte hnical. TheandInterlocked class type defines the static members shownarchitecturin Tablel issues10-9for. .NET developers.

Table 10-9: Members of the Interlocked Type

 

 

 

 

 

 

 

Table of Contents

 

 

Meaning in Life

 

C#Memberand the .NETof Platform,the

Second Edition

 

 

IntroductionSystem.Threading.Interlocked Type

 

 

 

 

 

 

 

 

Part One - Introducing C# and the .NET Platform

 

Safely increments a value by one

 

 

Increment()

 

 

 

 

Chapter 1

- The Philosophy of .NET

 

 

 

 

 

 

 

 

ChapterDecrement()2 - Building C# Applications

 

Safely decrements a value by one

 

 

 

 

 

 

Part Two - The C# Programming Language

 

Safely swaps two values

 

 

Exchange()

 

 

 

 

Chapter 3

- C# Language Fundamentals

 

 

 

 

 

 

 

 

ChapterCompareExchange()4 - Object-Oriented Programming with C#

 

Safely tests two values for equality, and if

 

 

Chapter 5

- Exceptions and Object Lifetime

 

so, changes one of the values with a third

 

 

 

 

 

 

 

 

Chapter 6

- Interfaces and Collections

 

 

 

Although it might not seem like it from the onset, the process of atomically altering a single value is quite

Chapter 7 - Callback Interfaces, Delegates, and Events

common in a multithreaded environment. Thus, rather than writing synchronization code such as the

Chapter 8 - Advanced C# Type Construction Techniques

following:

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

int i = 9;

Chapter 10 - Processes, AppDomains, Contexts, and Threads

lock(this)

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

{ i++; }

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms) you can simply write:

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

// Pass by reference the value you wish to alter.

Chapter 16 - The System.IO Namespace int i = 9;

Chapter 17 - Data Access with ADO.NET

Interlocked.Increment(ref i);

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

ChapterLikewise,19 if- youASP.wishNET Webto assignApplicationsthe value of a previously assigned System.Int32 to the value 83, you can

Chapteravoid the20need- XMLtoWeban explicitServiceslock statement (or Monitor logic) and make use of the Interlocked.Exchange()

Indmethod:x

List of Figures

List of Tables

int i = 9;

Interlocked.Exchange(ref i, 83);

Finally, if you wish to test two values for equality to change the point of comparison in a thread-safe manner, you would be able to leverage the Interlocked.CompareExchange() method as follows:

// If the value of i is currently 83, change i to 99.

Interlocked.CompareExchange(ref i, 99, 83);

SynchronizationC# and theUsing.NET Platform,the [Synchronization]Second Edition Attribute

by Andrew Troelsen

ISBN:1590590554

The final synchronization primitive examined here is the [Synchronized] attribute, which, as you recall, is a

Apress © 2003 (1200 pages)

contextual attribute that can be applied to context-bound objects. When you apply this attribute on a .NET

This comprehensive text starts with a brief overview of the

class type, you areC#effectivelylanguage andlockingthendownquicklyallmovesmembersto keyof theechnicalobjectandfor thread safety:

architectural issues for .NET developers.

using System.Runtime.Remoting.Contexts;

...

Table of Contents

// This context-bound type will only be loaded into a

C# and the .NET Platform, Second Edition

// synchronized (and hence, thread-safe) context.

Introduction

[Synchronization]

Part One - Introducing C# and the .NET Platform

public class MyThreadSafeObject : ContextBoundObject

Chapter 1 - The Philosophy of .NET

{ /* all methods on class are now thread safe */}

Chapter 2 - Building C# Applications

Part Two - The C# Programming Language

ChapterIn some3 ways,- C#thisLanguageapproachFundcanmentalsbe seen as the lazy approach to writing thread-safe code, given that we Chapterare not4required- Objectto-OridiventedintoProgrammingthe details aboutwithwhichC# aspects of the type are truly manipulating thread-

sensitive data. The major downfall of this approach, however, is that even if a given method is not making

Chapter 5 - Exceptions and Object Lifetime

use of thread-sensitive data, the CLR will still lock invocations to the method. Obviously, this could

Chapter 6 - Interfaces and Collections

degrade the overall functionality of the type, so use this technique with care.

Chapter 7 - Callback Interfaces, Delegates, and Events

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

Thread SafetyC# andandthe the.NET Platform,.NET BaseSecondClassEdition Libraries

by Andrew Troelsen

ISBN:1590590554

Although this chapter has illustrated how you can build custom thread-safe types, you should also be

Apress © 2003 (1200 pages)

aware that many of the types of the base class libraries have been preprogrammed to be thread-safe. In

This comprehensive text starts with a brief overview of the

fact, when you lookC#uplanguagea givenandtypethenusingquicklyonlinemovHelps to(suchkey technicalas Systemand.Console) you will find information regarding its levelarchitecturalof thread safetyissues(Figurefor .NET10developers-17). .

Table

C# and

Part

Chapter

Chapter

Part

Chapter

Chapter

Chapter

Chapter

Chapter

Chapter

Part

Chapter

Figure 10-17: Many (but not all) .NET types are already thread-safe .

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Sadly, many .NET types in the base class libraries are not thread-safe, and therefore, you will have to

Part Four - Leveraging the .NET Libraries

make use of the various locking techniques you have examined to ensure the object is able to survive

Chapter 12 - Object Serialization and the .NET Remoting Layer multiple requests from the thread base.

Chapter 13 - Building a Better Window (Introducing Windows Forms) Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

Console.WriteLine("Time is: {0}",
static void PrintTime(object state)

ProgrammingC# andwithhe .TimerNET Platform,CallbacksSecond Edition

by Andrew Troelsen

ISBN:1590590554

At this point you have seen a number of ways in which you are able to provide synchronized access to shared

Apress © 2003 (1200 pages)

blocks of data. To be sure, there are additional types under the System.Threading namespace, which I will allo

This comprehensive text starts with a brief overview of the

you to explore at C#yourlanguageleisure.andHowever,then quicklyto wrapmovesup ourto examinationkey technicalofandthread programming, allow me to introdu two additional types,architecturalTimerCallbackissues forand.NETTimerdevelopers. .

Many applications have the need to call a specific method during regular intervals of time. For example, you ma

TablehaveofanContentsapplication that needs to display the current time on a status bar via a given helper function. As anothe C#example,nd theyou.NETmayPlatform,wish toSecondhave yourEditionapplication call a helper function every so often to perform noncritical

background tasks such as checking for new e-mail messages. For situations such as these, the

Introduction

System.Threading.Timer type can be used in conjunction with a related delegate named TimerCallback.

Part One - Introducing C# and the .NET Platform

Chapter 1 - The Philosophy of .NET

To illustrate, assume you have a console application that will print the current time every second until the user h

Chapter 2 - Building C# Applications

a key to terminate the application. The first obvious step is to write the method that will be called by the Timer ty

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

class TimePrinter

Chapter 4 - Object-Oriented Programming with C#

{

Chapter 5 - Exceptions and Object Lifetime

Chapter 6 - Interfaces and Collections

{

Chapter 7 - Callback Interfaces, Delegates, and Events

Chapter 8 - Advanced C# Type Construction Techniques

DateTime.Now.ToLongTimeString());

Part Three - Programming with .NET Assemblies

}

Chapter 9 - Understanding .NET Assemblies

...

Chapter 10 - Processes, AppDomains, Contexts, and Threads

}

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

ChapterNotice 12how- thisObjectmethodSerializhastiona singlea d theparameter.NET R moftingtypeLayerSystem.Object and returns void. This is not optional, giv

that the TimerCallback delegate can only call methods that match this signature. The value passed into the tar

Chapter 13 - Building Better Window (Introducing Win ows Forms)

of your TimerCallback delegate can be any bit of information whatsoever (in the case of the e-mail example, th

Chapter 14 - A Better Painting Framework (GDI+)

parameter might represent the name of the MS Exchange server to interact with during the process). Also note

Chapter 15 - Programming with Windows Forms Controls

that given that this parameter is indeed a System.Object, you are able to pass in multiple arguments using a

Chapter 16 - The System.IO Namespace

System.Array type.

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

The next step would be to configure an instance of the TimerCallback type and pass it into the Timer object. In

Chapter 18 - ASP.NET Web Pages and Web Controls

addition to a TimerCallback delegate, the Timer constructor also allows you to specify the optional parameter

Chapter 19 - ASP.NET Web Applications

information to pass into the delegate target, the interval to poll the method, as well as the amount of time to wai

Chapter 20 - XML Web Services

before making the first call. For example:

Index

List of Figures

static void Main(string[] args)

List of Tables

{

Console.WriteLine("***** Working with Timer type *****\n");

// Create the delegate for the Timer type.

TimerCallback timeCB = new TimerCallback(PrintTime);

// Establish timer settings.

Timer t = new Timer(

timeCB,

// The

TimerCallback delegate type.

null,

// Any

info

to

pass

into the called method (null for no inf

0,

//

Amount of time to wait before starting.

1000);

//

Interval

of

time

between calls.

Console.WriteLine("Hit key to terminate...");

Console.ReadLine();

}

In this case, the PrintTime() method will be called roughly every second, and will pass in no additional informati

to said method. If you did wish to send in some information for use by the delegate target, simply substitute the

C# and the .NET Platform, Second Edition

value of the second constructor parameter with the appropriate information. For example, ponder the following

updates:

by Andrew Troelsen

ISBN:1590590554

Apress © 2003 (1200 pages)

 

 

 

This comprehensive text starts with a brief overview of the

static void PrintTime(object state)

C# language and then quickly moves to key technical and

{architectural issues for .NET developers.

Console.WriteLine("Time is: {0}, Param is: {1}",

DateTime.Now.ToLongTimeString(), state.ToString());

Table} of Contents

...

C# and the .NET Platform, Second Edition

Timer t = new Timer(timeCB, "Hi", 0, 1000);

Introduction

Part One - Introducing C# and the .NET Platform

Chapter 1 - The Philosophy of .NET

Figure 10-18 shows the output.

Chapter 2 - Building C# Applications

Part Two - The C# Programming Language

Chapter

 

Chapter

C#

Chapter

 

Chapter

 

Chapter

Events

Chapter

Techniques

Part

Figure 10-18: The (very useful) console-based clock application

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

SOURCE The TimerApp application is included under the Chapter 10 subdirectory.

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

CODE

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

That wraps up our examination of multithreaded programming under .NET. To be sure, the System.Threading Chnamespacept r 13 - BuildingdefinesanumerousBetter Windowtypes(IntrbeyondducingwhatWindowsI had theForms)space to examine in this chapter. Nevertheless, at t

Chapterpoint you14should- A BetterhavePaintingsolidFrameworkfoundation(GDI+)to build on.

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

Соседние файлы в предмете Программирование