- •Table of Contents
- •C# and the .NET Platform, Second Edition
- •Introduction
- •Part One: Introducing C# and the .NET Platform
- •Part Two: The C# Programming Language
- •Part Three: Programming with .NET Assemblies
- •Part Four: Leveraging the .NET Libraries
- •Part Five: Web Applications and XML Web Services
- •Obtaining This Book's Source Code
- •The .NET Solution
- •What C# Brings to the Table
- •The Role of the Assembly Manifest
- •Summary
- •Chapter 2: Building C# Applications
- •Summary
- •Chapter 3: C# Language Fundamentals
- •Defining Program Constants
- •Defining Custom Class Methods
- •C# Enumerations
- •Summary
- •The Second Pillar: C#'s Inheritance Support
- •Summary
- •Catching Exceptions
- •Finalizing a Type
- •Garbage Collection Optimizations
- •Summary
- •Chapter 6: Interfaces and Collections
- •Building Comparable Objects (IComparable)
- •Summary
- •Summary
- •Internal Representation of Type Indexers
- •Summary
- •An Overview of .NET Assemblies
- •Understanding Delayed Signing
- •Using a Shared Assembly
- •GAC Internals
- •Summary
- •Spawning Secondary Threads
- •A More Elaborate Threading Example
- •Summary
- •Summary
- •Object Persistence in the .NET Framework
- •The .NET Remoting Namespaces
- •Understanding the .NET Remoting Framework
- •All Together Now!
- •Terms of the .NET Remoting Trade
- •Testing the Remoting Application
- •Revisiting the Activation Mode of WKO Types
- •Deploying the Server to a Remote Machine
- •Summary
- •Control Events
- •The Form Class
- •Summary
- •Regarding the Disposal of System.Drawing Types
- •Understanding the Graphics Class
- •Summary
- •The TextBox Control
- •Working with Panel Controls
- •Configuring a Control's Anchoring Behavior
- •Summary
- •Chapter 16: The System.IO Namespace
- •The Static Members of the Directory Class
- •The Abstract Stream Class
- •Summary
- •The Role of ADO.NET Data Providers
- •The Types of System.Data
- •Selecting a Data Provider
- •The Types of the System.Data.OleDb Namespace
- •Working with the OleDbDataReader
- •Summary
- •Submitting the Form Data (GET and POST)
- •Some Benefits of ASP.NET
- •Creating an ASP.NET Web Application by Hand
- •The Composition of an ASP.NET Page
- •The Derivation of an ASP.NET Page
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
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
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
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
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