advanced language concepts in c# david figge [email protected] session 3 last update: 3/09page...

68
Advanced Language Concepts in C# David Figge [email protected] Session 3 Last Update: 3/09 Page 1 Copyright (C) 2009 by David Figge. All Rights Reserved.

Post on 20-Dec-2015

219 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Advanced Language Concepts in C#

David [email protected]

Session 3

Last Update: 3/09 Page 1

Page 2: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Advanced Language Concepts in C#

Where We’re at, Where We’re Going…

Last Update: 3/09 Page 2

Page 3: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Session 1: Review, Introductions Language INtegrated Query

(LINQ) Session 2:

More Linq (continued) Session 3:

Still More Linq (continued) Session 4:

Creating tables in a Database Attributes

Session 5: Relationships and Referential

Integrity Session 6:

Displaying XML data with DataGrid

Nullable Types SQL Security Concepts .Net Security

Session 7: Class Libraries Namespaces and Assemblies Versioning Global Assembly Cache (GAC) Extern Aliases

Session 8: Multi-Threading

Session 9: Anonymous Methods Integrating Help Localization Windows Setup/Click-Once

Deployment Session 10:

Final Project

Class 3 Schedule

Last Update: 3/09 Page 3

Page 4: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Advanced Language Concepts in C#

Working with Class Libraries, Namespaces, and

Assemblies

Last Update: 3/09 Page 4

Page 5: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Assemblies

In .Net, a deployable unit of code is called an Assembly

Typically, it consists of one module, created by compiling one or more source files into an .exe or .dll file

We’ve been building our Address program into a single module assembly called address.exe

.Net does support multi-module assemblies I’m not going to go into that here

Visual Studio doesn’t support it So you’d have to use to command-line compiler with options

It’s not commonly needed Instructions to do this are in the book

Let's see more about assemblies…

Last Update: 3/09 Page 5

Page 6: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Assembly Characteristics

A binary file hosted by the CLR Although they use the standard executable file format

for Windows, it loads the CLR first, then passes to the CLR the assembly start point

Typically has either an .exe or a .dll extension But can also have other extensions

Establish a type boundary So if two assemblies define the same type, each is seen

as unique to its assembly Support version numbers

The format is <major>.<minor>.<build>.<revision> Along with an optional public key (“strongly named”),

this allows multiple versions of the same assembly to coexist on the machine

More on this later

Last Update: 3/09 Page 6

Page 7: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Assembly Characteristics

Self Describing This means two things

All assemblies used by this one are specifically referenced so they can be loaded as the program starts

Although you can manually load assemblies at runtime outside of this

The assembly has metadata describing the functions in it

You can access this information through the Reflection API

Configurable Can be deployed as private or shared

More on this later Config files can also be used to define locations

and loading options

Last Update: 3/09 Page 7

Page 8: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Namespaces

When projects get large or use multiple assemblies, the potential for naming conflicts increases

To help manage these conflicts, Namespaces are used to identify groups of classes that go together Typically, by the source file or assembly they're

in Namespaces are defined using the

Namespace keyword You can define new namespaces at any time you

see a value Let's see an example of Namespaces…

Last Update: 3/09 Page 8

Page 9: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Example Namespace

namespace MyShapes{

class Circle { ... }class Triangle { ... }class Square { ... }

}

// Using the namespace (separate program...)using System;using MyShapes;namespace MyApp{

class MyAppClass {static void Main(string[] args){

Circle c = new Circle(); // Or = new MyShapes.Circle()Square s = new Square(); // fully qualified can avoidTriangle t = new Triangle(); // namespace clashes

}}

}

Last Update: 3/09 Page 9

So here we have an example of the MyShapes namespace defined in, say, an

add-on DLL.To use the namespace in our application, we simply put a using statement (you may need to add a

reference if the namespace is in another assembly).

Note the alternative to including the using statement would be to fully

reference Circle, like

Circle c = new MyShapes.Circle();

Using a fully qualified path can avoid namespace clashes

Making senseso far?

Page 10: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Aliases

C# also supports the use of aliases These can come in handy when you

have two namespaces that have similar functionality

Let's look at an example…

Last Update: 3/09 Page 10

Page 11: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Alias Example

// In Bob.dll, namespace Bob, who works in the CoolVisuals product division at BigCorpnamespace Graphics{

class Circle { ... } // Bob’s Circle function is really fastclass Triangle { ... }class Square { ... }

}// In Sue.dll, namespace Sue. Sue works at SmallShop in competition with BigCorp and Bobnamespace Graphics{

class Circle { ... }class Triangle { ... } // But Sue’s triangle function beats Bob’s every timeclass Square { ... }

}

// separate program...using System;using BigCorp.CoolVisuals.Bob.Graphics;using SmallShop.AlsoCoolVisuals.Sue.Graphics;namespace MyApp{

class MyAppClass {static void Main(string[] args){

Circle c = new Circle(); // Ambiguous. C# doesn’t know which you mean!Triangle t = new Triangle();

}}

}

Last Update: 3/09 Page 11

So Bob, who works for the CoolVisuals group at BigCorp has a set

of graphics functions. They aren’t spectacular, except for his Circle

function, which is really fast.

Sue, who works has a product AlsoCoolVisuals, published by

SmallShop. Sue’s Triangle function is much better than Bob’s.

So now we’re ready to use Bob’s circle and Sue’s Triangle. But there’s a problem. Since we included both using

statements, there are now two circle and two triangle functions (not to mention the squares!). We could fully

qualify all our uses, but that would be awkward…

Circle c = new BigCorp.CoolVisuals.Bob.Graphics.Circle()

This is where aliases come in…

Page 12: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Alias Example

// In Bob.dll, namespace Bob, who works in the CoolVisuals product division at BigCorpnamespace Graphics{

class Circle { ... } // Bob’s Circle function is really fastclass Triangle { ... }class Square { ... }

}// In Sue.dll, namespace Sue. Sue works at SmallShop in competition with BigCorp and Bobnamespace Graphics{

class Circle { ... }class Triangle { ... } // But Sue’s triangle function beats Bob’s every timeclass Square { ... }

}

// separate program...using System;using bobs = BigCorp.CoolVisuals.Bob.Graphics;using sues = SmallShop.AlsoCoolVisuals.Sue.Graphics;namespace MyApp{

class MyAppClass {static void Main(string[] args){

Circle c = new bobs.Circle(); // Uses Bob.GraphicsTriangle t = new sues.Triangle(); // Uses Sue.Graphics

}}

}

Last Update: 3/09 Page 12

This is the syntax for an Alias. It allows you to define an identifier that is a

placeholder for a namespace.

By using the alias, the namespaces are clear, and the code is easy to read.

Questionson that?

Page 13: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Namespaces

You can also nest namespaces By default, VS creates a namespace

for your app Same as the name of your app Change this using the Default

Namespace setting in the Application tab of the project properties.

Last Update: 3/09 Page 13

Page 14: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Applications vs. Class Libraries

An application consists of A collection of functions

One of which must be Main Resources (memory, etc) An execution context (a “thread”)

This includes a stack A class library (aka code library) consists of

A collection of functions Resources (optional)

So a class library is simply a collection of functions available to other programs

It uses the calling program’s context for execution

i.e. its memory space, its “thread space”, etcLast Update: 3/09 Page 14

Page 15: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Let’s Try It…

Open up your Address program Create a new project (part of the

solution) Type is a Class Library

So you'll be able to use this for other apps as well

Call it IUtils, for Internet Utilities In it, put this code…

Last Update: 3/09 Page 15

Page 16: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Locate Function

namespace IUtils{ public class Maps { public static void Lookup(string address, string csz) { string combined = address + ", " + csz; // Add+CSZ string converted = combined.Replace(' ', '+'); // repl sp with + string args = "maps.google.com/maps?q=" + converted;// Full URL

// Fire off IE as a new process System.Diagnostics.Process proc = new System.Diagnostics.Process(); proc.EnableRaisingEvents = false; proc.StartInfo.FileName = "iexplore.exe"; proc.StartInfo.Arguments = args; proc.StartInfo.UseShellExecute = true; proc.Start(); } }}

Last Update: 3/09 Page 16

Page 17: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Using IUtils from Address

Make sure IUtils builds Add a reference to IUtils from

Address Add a new button to the Address

form Call it btnMap In it, we will call the Map.Locate

function in IUtils Here’s the code…

Last Update: 3/09 Page 17

Page 18: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Calling the Locate Function

private void btnMap_Click(object sender, EventArgs e){ Entry ent = SelectedEntries[current]; IUtils.Maps.Lookup(ent.Address, ent.CSZ);}

Last Update: 3/09 Page 18Type it in. It should work…

Page 19: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Private Assemblies

The IUtils DLL is a private assembly It’s required to be in the same directory as the exe

You can dynamically load it (i.e. as it is running) from any location

You can also use another location using a config file (in this case, IUtils.config) to specify location

the book has more on this

You can see it there now By defining a reference to it, the DLL gets placed in

there .Net does not use the registry when searching for DLLs Copying to another location is easy (unlike COM)

copy all files in the directory Private assemblies don’t specifically use version

numbers, as this is the only app that uses the DLL where it is

Last Update: 3/09 Page 19

Page 20: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Shared Assemblies

Like private assemblies, shared assemblies contain functions and (optionally) data that programs can use

Shared assemblies, however, are available to all .Net apps that want to use them. The .Net framework assemblies are, for

example, shared assemblies So, what has to happen to make a

shared assembly?Last Update: 3/09 Page 20

Page 21: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Shared Assemblies

Shared Assemblies are placed in a commonly accessible location on your machine called the Global Assembly Cache, or the GAC Located at \windows\assembly Note that only *.dll assemblies can be stored in

the GAC (not even *.exe) Shared assemblies must have Strong

Names This uniquely identifies the publisher of the

assembly This could be a developer, a department, or a

company as a wholeLast Update: 3/09 Page 21

Page 22: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Strong Names

The strong name creates a unique identifier for the assembly

Similar to the GUID for COM objects Strong names make use of public key/private key

encryption Formally, they consist of

The friendly name of the assembly The name of the assembly minus the extension

The version number of the assembly Defined in the Build properties via VS

The public key value Also defined in the Build properties via VS

An optional culture identity value for localization An embedded digital signature

A combination of a hash of the assembly’s contents and the private key value

Let’s apply a strong name to our IUtils DLL…

Last Update: 3/09 Page 22

Page 23: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Strong Names

In Project Properties / Signing Select Sign the assembly Under Choose a Strong Name Key File

Select <New…> Enter a name (IUtils) and a password of

your choice That's it. You're good. Rebuild it and copy it to the GAC

Easiest way is to drag into the GAC Copy/Paste won't work…

Last Update: 3/09 Page 23

Page 24: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Strong Names

Note that strong names also provide some protection against tampering

Generally, it’s a good idea to strongly name every assembly intended for public consumption (even if private)

Last Update: 3/09 Page 24

Page 25: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Extern Alias

An extern alias is used to reference to assemblies with the same fully qualified type name but different version numbers

To reference two assemblies with the same fully-qualified type names, an alias must be specified on the compiler command line, like this:

/r:GridV1=grid.dll /r:GridV2=grid20.dll

This creates the external aliases GridV1 and GridV2. To use these aliases from within a program, reference them using the extern keyword. For example:

extern alias GridV1; extern alias GridV2;

Last Update: 3/09 Page 25

Page 26: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

A Chance to Play

Last Update: 3/09

In this exercise you will build an additional DLL assembly and use it from the Address program

The DLL will have one function, called CopyToClipboard It is a utility that will copy any number of

strings to the system clipboard for pasting into other apps. In our case, it will be the entry currently displayed on the window

The DLL you create will be a shared assembly (so others can use it too )

Page 26

Page 27: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

The AddressUtils DLL

Last Update: 3/09

Create the AddressUtils DLL as an additional project in your solution

Add a reference to System.Windows.Forms So you can access the clipboard

In it, create a ClipboardUtils class, with CopyToClipboard in it public static void CopyToClipboard(params string[] p)

p is an array of strings passed by the caller Create one big long string consisting of each string in p followed by “\r\n” (each

one) Call Clipboard.Clear() to erase current clipboard contents Call Clipboard.SetText() to set the new contents to your string

From your address program Call this function copying the Name, Address, and CSZ to the clipboard

When it’s working, make the DLL a shared DLL by Signing it Placing it in the GAC

Good Luck!

Page 27

30 Minutes

Page 28: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Advanced Language Concepts in C#

Working with Threads

Last Update: 3/09 Page 28

Page 29: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Threads

What are threads? A thread is a “line of execution” within a process

Why are they used? To perform lengthy processes in the background

For example, loading a large image To wait for external event

For example, waiting for device to become ready To perform long-term background tasks

For example, to update a clock on the display To perform a task but keep Windows form responsive

For example, sending a file across the network When should I consider using threads in my program?

If the user interface responsiveness becomes too slow When task can easily execute in background (and is somewhat

autonomous, like printing a file) When it makes sense organizationally (for example, two tasks

that don’t interact and can be done simultaneously)

Last Update: 3/09 Page 29

Page 30: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Thread Basics

In Windows, a thread is always contained in a process

The process “owns” the addressspace and system resources fora program

So all threads within a processhave access to the same memory,variables, functions, etc.

In a single processor machine Only one thread is actually running at a time Periodically (every 20 ms or so) the Windows

OS stops the current thread and swaps it outfor another thread that’s ready to run

This is called a Timeslice or Quantum On a dual CPU system, 2 threads are run

at a time (one for each CPU)Last Update: 3/09 Page 30

Process

Memory

Thread 1

Thread 2

FilesPorts

Page 31: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Thread Basics

Thread States Threads are always in one of several

states. The most significant states are Ready (waiting for its turn on the CPU) Running (only one per CPU is in this state) Waiting on outside event

For example, file I/O. When this event happens, an interrupt occurs. At

that point, data is placed into its destination buffer, and the waiting thread is moved to the Ready state

Last Update: 3/09 Page 31

Page 32: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Thread Basics

Threads and Scheduling Windows schedules threads (not processes) Threads have priority

Numbered 0-32. Above 16 is called ‘realtime’ Threads with higher priority are always run if ready

(that’s how the scheduler works) So, if my thread is higher priority than yours, yours will

stop until my thread is complete, then yours runs again Normal is about 8. Multimedia runs at about 27.

By default, the thread inherits the priority of the process creating it.

You can change your thread’s priority, but you typically leave it alone unless there’s good reason to change it

Last Update: 3/09 Page 32

Page 33: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Threads

How do I create threads? Threads are supported in the

System.Threading namespace You create a thread by

Creating an instance of the Thread class You pass in the function to execute This just creates the object, it’s not going yet

Calling the Start() method This executes the thread It may not run until your timeslice is complete

Let’s create a simple console app to play with threading…

Last Update: 3/09 Page 33

Page 34: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Thread Example: Destination

static string[] destinations = { "Honolulu", "San Francisco", "Miami", "Cleveland" };static void Main(string[] args){ Destination();}static void Destination(){ Random r = new Random(); for (int x = 0; x < 25; x++) { int y = r.Next() % 4; // Choose a random

city Console.WriteLine(destinations[y]); // Display it }}

Last Update: 3/09 Page 34Type it in, then we’ll look at it. It should work…

Page 35: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Thread Example: Destination

So this gives us a reasonable way to choose which city we should use for our next vacation Mostly, it gives us something to play

with using threads So, if one call to the destination

function is good, four must be even better, right? Let’s modify this so that we run 4

concurrent threads calculating our destination…

Last Update: 3/09 Page 35

Page 36: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Thread Example: Destination

static string[] destinations = { "Honolulu" ...,static void Main(string[] args){ Thread[] t = new Thread[4]; // uses System.Threading for (int x = 0; x < 4; x++) { t[x] = new Thread(Destination); t[x].Name = "Thread" + x; t[x].Start(); }}static void Destination(){ Random r = new Random(); for (int x = 0; x < 25; x++) { int y = r.Next() % 4; Console.WriteLine(Thread.CurrentThread.Name + ": " + destinations[y]); }}

Last Update: 3/09 Page 36Once again, type it in, then we’ll talk…

So, as you see, we create an array of 4 Threads.

For each one, we create the Thread object by passing the name of the

function associated with the thread. Like Main, when that function ends,

the thread terminates.

Threads have several useful properties associated with them.

Here we’re using the Name property, so we can tell each of them apart from one another.

Threads are not actually started until you call the Start function. At

that point, the thread will be placed in the queue for the next

available timeslice.

Everyone have it working? Making sense?

Page 37: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Thread Example: Destination

So we now have 4 threads executing the same function simultaneously

Remember, to create a thread Create the object, passing the name of

the thread function to the constructor Call the .Start() method of the new

thread object It will not start until you do this

You can also pass a parameter to the thread function. Let’s see how that’s different…

Last Update: 3/09 Page 37

Page 38: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Thread Example: Destination

static string[] destinations = { "Honolulu" ...,static void Main(string[] args){ Thread[] t = new Thread[4]; // uses System.Threading for (int x = 0; x < 4; x++) { t[x] = new Thread(Destination); // t[x].Name = "Thread" + x; t[x].Start("Thread " + x); }}static void Destination(object name){ string MyName = (string)name; Random r = new Random(); for (int x = 0; x < 25; x++) { int y = r.Next() % 4; Console.WriteLine(MyName + ": " + destinations[y]); }}

Last Update: 3/09 Page 38Go ahead and get these changes in…

So, as you can see, we’re simply passing the name of the thread as a

parameter. Any object can be passed as the parameter (so, for

example, an array of settings)

Questionson this?

Page 39: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Thread.Sleep()

The Sleep function is used to cause the current thread to stop executing for a specific number of milliseconds.

For example, Thread.Sleep(100) The milliseconds is approximate.

You will not return for at least 100 ms, but may be longer than that This can be useful when you’re waiting for something to

occur, and simply need to check it periodically to see if it is ready

It can also be useful when something is timed For example, counting down seconds. You can update the

time then sleep for 1 second (1000 ms) You can also use timers for these if needing it for an

extended time or often Let’s add a Sleep in our code to make sure someone

else gets a chance after we’ve printed our destination This should stop multiple prints from the same thread

Last Update: 3/09 Page 39

Page 40: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Thread Example: Destination

static void Destination(object name){ string MyName = (string)name; Random r = new Random(); for (int x = 0; x < 25; x++) { int y = r.Next() % 4; Console.WriteLine(MyName + ": " + destinations[y]); Thread.Sleep(5); }}

Last Update: 3/09 Page 40

Is this making sense?

Okay, so let’s put in another change and see what happens…

Page 41: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Thread Example: Destination

static string[] destinations = { "Honolulu" ...,static StringBuilder dest = new StringBuilder();static void Main(string[] args){ ...}static void Destination(object name){ string MyName = (string)name; Random r = new Random(); for (int x = 0; x < 25; x++) { int y = r.Next() % 4; dest.Length = 0; // Start new word for (int z = 0; z < destinations[y].Length; z++) { dest.Append(destinations[y][z]); // Copy destination to dest Thread.Sleep(1); // Pause a little } Console.WriteLine(MyName + ": " + dest); // Write destination out Thread.Sleep(5); }}

Last Update: 3/09 Page 41Put this in and see what happens…

Page 42: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Thread Example: Destination

So what happened?!? The dest variable is an example of a shared resource

An element of the program that is (potentially) used by more than one thread at a time

What we saw was an example of Collision Where two threads USED the same resource at the same time

Generally, you want to avoid having shared resources They act as bottle-necks to the program In our case, simply making dest a local (non-static) variable would

solve that What are some real-world examples of shared resources?

I thought of: An airplane bathroom, public bathrooms in general (a limited number of resources, even if more than one), telephones, cars, televisions…

What are some computer examples of shared resources I thought of: print spoolers, shared output files, network

communications (pipes), the console output screen, databases! Anything that has only one access point and isn’t built to support

multiple threads communicating through it simultaneously

Last Update: 3/09 Page 42

Page 43: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Avoiding Collisions

Collisions are worth avoiding They can corrupt data and can be very hard to find

How do we avoid collisions on an airplane bathroom?

A C# lock is used in the same way You ask for a resource If it’s available, you lock it, use it, unlock it If it’s unavailable, you wait until whoever has it

unlocks it (releases the lock) All objects in C# can be used in a lock

You just need to make sure everyone using the same resource is using the same lock object

Let’s see how that works…

Last Update: 3/09 Page 43

Page 44: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Thread Example: Destination

static string[] destinations = { "Honolulu" ...,static StringBuilder dest = new StringBuilder();static void Main(string[] args){ ...}static void Destination(object name){ string MyName = (string)name; Random r = new Random(); for (int x = 0; x < 25; x++) { int y = r.Next() % 4; lock(dest) // Apply lock via dest { dest.Length = 0; for (int z = 0; z < destinations[y].Length; z++) { dest.Append(destinations[y][z]); Thread.Sleep(1); } Console.WriteLine(MyName + ": " + dest); } // Release the lock Thread.Sleep(5); }}

Last Update: 3/09 Page 44Add this, then we’ll talk…

So only one thread can get into this code at a time. If someone else has dest locked, you must

wait for it to be released. When it’s released, a mad scramble

happens to determine who gets to be the next thread. The operating

system ensures that only one thread gets in at a time.

The lock is released at the end of the code block.

This section of code is referred to as a Critical

Section, because it’s limited to one thread at a time.

Still making sense?

Page 45: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Deadlock

An important concern anytime you’re using shared resources/locks is deadlock (“Deadly Embrace”)

An example of deadlock situation might be the following

Thread 1 needs to update files A,B, and C Thread 2 needs to update F, and C, and B To begin

Thread 1 Starts the process by locking files A and B for update Thread 2 also starts and locks F and C

And now At this point, thread 1 tries to lock C, but thread 2 has it. Meanwhile thread 2 is waiting for file B to be released, but thread

1 has it Both threads are waiting for resources the other has, and aren’t

planning on giving them up until they’re done You now have a deadlock situation in which the program

hangs.

Last Update: 3/09 Page 45

Page 46: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Deadlock

The two key elements to deadlock avoidance are Be aware that it happens. Look for

situations where this may occur. If you can, avoid them

If you can’t, set up a timeout situation If thread 1 is waiting for a file lock for, say,

more than 500ms Stop. Release all the locks it currently has. Wait a random (short) time Reacquire the locks

If all your threads do this, you can avoid deadlock situations

Last Update: 3/09 Page 46

Page 47: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Background Threads

We’ve been dealing with Foreground Threads These are critical to the program and the

program does not end until these threads do The more common thread is a

Background Thread This thread runs normally, but if the program

is exited, the thread is killed In Windows, you generally want your threads

to be background threads Let’s make our threads background

threads

Last Update: 3/09 Page 47

Page 48: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Thread Example: Destination

static string[] destinations = { "Honolulu" ...,static void Main(string[] args){ Thread[] t = new Thread[4]; // uses System.Threading for (int x = 0; x < 4; x++) { t[x] = new Thread(Destination); t[x].IsBackground = true; // Mark threads as background t[x].Start("Thread " + x); }}

Last Update: 3/09 Page 48

Page 49: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Background Threads

What happened? By making the “Destination” threads

background threads, we said, “If the program ends, kill these threads”

The main program ended when Main was done executing

You can suspend the current thread until another thread completes by the Join() method…

Last Update: 3/09 Page 49

Page 50: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Thread Example: Destination

static string[] destinations = { "Honolulu" ...,static void Main(string[] args){ Thread[] t = new Thread[4]; // uses System.Threading for (int x = 0; x < 4; x++) { t[x] = new Thread(Destination); t[x].IsBackground = true; t[x].Start("Thread " + x); } t[0].Join(); // Wait for threads to complete t[1].Join(); t[2].Join(); t[3].Join();}

Last Update: 3/09 Page 50

Page 51: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Race Conditions

In addition to deadlocks, you also need to keep an eye out for race conditions

A race condition is where one thread assumes a second thread has completed enough of its work for the first thread to go forward

An example Thread 1’s job is to open a file In the meantime, thread 2 is processing the information

that’s going to go in the file Since this takes about 2 seconds, thread 1 should be easily

finished when this is done, so thread 2 just writes the data to the file thread 1 just opened.

But, what if thread 1 was delayed opening the file (maybe another process had it locked…)

In this case, thread 2 would try to write data to a closed file (and fail, obviously)

Last Update: 3/09 Page 51

Page 52: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Race Conditions

You can easily avoid race conditions with two steps

Be aware that it happens. Look for situations where this may occur. If you can, avoid them.

If you can’t, simply have a flag that thread 1 sets when the file is opened.

Thread 2 then makes sure that the flag is set before continuing with the writing

If it isn’t set, either wait (sleeping is best) for it to be set or throw an exception

You can also use Events (AutoResetEvent and ManualResetEvent)

Technically, our previous problem was in our program was a race condition

Our main thread ‘assumed’ the other threads had completed and exited the program

Last Update: 3/09 Page 52

Page 53: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Background Threads

When a C# application starts, it is given one thread

This thread is intended for use by the UI, and not for significant background processes

If you use this thread for lengthy operations, it will appear to hang the UI

If this happens, the first step is to set the form’s cursor to the hourglass

But this still causes the UI to hang, so don’t do this too long The next step would be to use a background thread to

perform the operation Ideally, the main program could continue But even if the main program has to wait, at least you could

have a cancel button to abort Printing is an obvious example However, you run into a problem…

Last Update: 3/09 Page 53

Page 54: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

The UI Problem

Say, for example, you have a print option that displays its progress to a ProgressBar control

Simple, right… Create the form and display it Start the printing thread

As the print thread progresses, have it update its progress on the progress bar control

When it’s done, it closes the “printing” form Unfortunately, it’s not quite that simple

For one thing, only the thread that created the control can access it

This is because controls aren’t designed to be accessed by multiple threads at the same time

Last Update: 3/09 Page 54

Page 55: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

The BackgroundWorker

The solution to this is a thread class specifically designed for background tasks called the BackgroundWorker

Among other things, it let’s you Specify the function that does the work Specify a function that updates

progress Specify a function to cancel the

operation Specify a function to call when the job’s

doneLast Update: 3/09 Page 55

Page 56: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Class Exercise

Last Update: 3/09

Going back to our Address program, let’s add a “Print” button that uses the BackgroundWorker class to simulate printing a record to the printer In our case, instead of actually printing,

we’re going to wait for 5 seconds As we wait, we’ll display a progress bar If you wish, you can swap this code later

for code that actually prints But this also gave us the opportunity to look

at progress bars Page 56

Page 57: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Printing: Step 1 – the Print Form

Create a form like this: Call in frmPrint Button: btnCancel Progress Bar: pBar

Proper OOP design says that the form should be in charge of its own controls, so add these functions to the frmPrint code…

Last Update: 3/09 Page 57

Page 58: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example Print Form Code

BackgroundWorker WorkerThread; // The ‘printing’ threadpublic frmPrint(BackgroundWorker thread){ WorkerThread = thread; // Save so we could cancel InitializeComponent();}

public void UpdateProgress(int amt){ pBar.Value = amt; // Progress so far}

// Add this function by double-clicking the cancel buttonprivate void btnCancel_Click(object sender,RoutedEventArgs e){ WorkerThread.CancelAsync(); // Cancel printing}

Last Update: 3/09 Page 58As usual, type, then talk. It won’t work for a while…

UpdateProgress is used to update the progress bar.

That’s done simply by setting the .Value property

of the bar.

If the user presses the Cancel button, we need to signal to the BackgroundWorker thread that it

needs to abort. We do that by calling its CancelAsync method. Of course, to do that, we need access to the BackgroundWorker thread

object…

So we modify the constructor to take the

BackgroundWorker thread object, and store it into a class variable.

Is this making senseso far?

Page 59: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Printing: Step 2 – the Print Button

Add a button to your main Address Book form called btnPrint. Double-click it to create the btnPrint_Click method

In this method we’ll Create the BackgroundWorker thread Point its delegates to functions that

Do the work (simulate printing) Update the progress bar Complete the printing

Create the frmPrint form Start the ‘printing’ process Display the frmPrint form with ShowDialog

Last Update: 3/09 Page 59

Page 60: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example btnPrint Code

frmPrint printform = null; // New Class Variableprivate void btnPrint_Click(object sender,RoutedEventArgs e)

{ BackgroundWorker printthread = new BackgroundWorker(); printthread.DoWork += Print; printthread.ProgressChanged += PrintProgress; printthread.RunWorkerCompleted += PrintCompleted; printthread.WorkerReportsProgress = true; printthread.WorkerSupportsCancellation = true;

printform = new frmPrint(printthread); // Create form printthread.RunWorkerAsync(); // Call DoWork() // Display form, if cancelled say so if (printform.ShowDialog() == false) MessageBox.Show("Printing Aborted");}

Last Update: 3/09 Page 60Type this in. It still won’t work, but we’re closer…

So the BackgroundWorker class has several delegates that point to functions used. Here

we set up those delegates to point to our functions. Questions on that part?

Next we set some flags to show what

capabilities we’re supporting (report

progress and cancel).Next we create the frmPrint object, passing the BackgroundWorker thread (so it can cancel)

Before we display the form, we need to start the printing. This is (ultimately)

calling the .Start method on the thread.

Now we display the dialog box. When it

comes back, printing is either completed or was

cancelled.

Questions onthis code?

Page 61: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

The PrintProgress Function

The PrintProgress function’s purpose is to update the Progress Bar to the current state of the “printing” Note that this function is called in the context of

the UI thread, so it can update the control without throwing an exception

Progress default to counting from 0 to 100 (i.e. percent) We’ll call this function every 5 percent of the

way through the ‘printing’ This function will simply pass this on to the

printform’s UpdateProgress function Here’s the code…

Last Update: 3/09 Page 61

Page 62: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example The PrintProgress Function

private void PrintProgress(object sender, ProgressChangedEventArgs e){ printform.UpdateProgress(e.ProgressPercentage);}

Last Update: 3/09 Page 62Get this typed in first, then we’ll cover it…

This is accessed through the ProgressChanged delegate of the

BackgroundWorker. When we call that delegate, we specify what progress we’ve

made, which is placed into the ProgressPercentage variable. We’ll cover

that shortly.

Page 63: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

The PrintCompleted Function

The PrintCompleted function is called in one of two circumstances Both indicate that the process is done First: print finished normally Second: printing was aborted

So our code will tell the Print form to return either DialogResult.OK or DialogResult.Cancel based on if it was cancelled or not

Here’s that code…

Last Update: 3/09 Page 63

Page 64: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example The PrintCompleted Function

private void PrintCompleted(object sender, RunWorkerCompletedEventArgs e){ printform.DialogResult = (e.Cancelled == true ? false : true); printform.Close();}

Last Update: 3/09 Page 64Type, then talk…

This is called automatically when the Thread’s function ends. We set the

DialogResult property of the frmPrint to indicate whether we ended by

completion or cancelation. Then we close the dialog box (returning to the btnPrint

function).

Page 65: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

The Print Function

Finally we’re ready for the Print function itself

Remember its purpose is to Run for about 5 seconds Update the progress bar every 5% Cancel the process if the cancel button was

pressed The button press called AsyncCancel Which sets the CancellationPending flag of the

DoWorkEventArgs argument So we’ll check that

End when we’ve done 100% of the work Here’s the code…

Last Update: 3/09 Page 65

Page 66: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Code

Example The Print Function

public void Print(object sender, DoWorkEventArgs e){ BackgroundWorker thread = (BackgroundWorker)sender; int currentpct = 0; do { if (thread.CancellationPending) { e.Cancel = true; return; } thread.ReportProgress(currentpct); Thread.Sleep(250); currentpct += 5; } while (currentpct <= 100);}

Last Update: 3/09 Page 66The final code. Type it in, it should work…

We start by taking sender (which is the

BackgroundWorker) and saving it so we can use it

later.

Within our loop, we first see if we’ve been asked to cancel. If so, we set the

cancel flag to true and exit the function (which calls the PrintCompleted function

automatically)

Otherwise, we report our progress (which calls

our PrintProgress function, which updates

the progress bar).

We simulate printing activity by sleeping for a

¼ second…Change our progress

status…And keep it up until

we’re done (at which point we exit, and

PrintCompleted is called automatically)

There’s a lot here. Any questions on this?

Page 67: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Thread Summary

Threads are worth considering when Working in foreground thread is too long When task is somewhat stand-alone and can easily execute

in background It makes sense organizationally

Create a thread via the Thread class Pass the function to execute Call the Start() method to begin the thread Call the Join() function to wait for it to end

Be aware of Collisions (use locks to avoid this) Deadlock (use timeouts to avoid this) Race conditions (use flags to avoid this)

The BackgroundWorker class is convenient Allows easy creation of background tasks Supports UI updates on progress and easy cancellation

Last Update: 3/09 Page 67

Any questionson threads?

Page 68: Advanced Language Concepts in C# David Figge dfigge@u.washington.edu Session 3 Last Update: 3/09Page 1Copyright (C) 2009 by David Figge. All Rights Reserved

Copyright (C) 2009 by David Figge. All Rights Reserved.

Advanced Language Concepts in C#

End of Session 3

Last Update: 3/09 Page 68