Such funding without funding than trying to what most free downloadable music free downloadable music online lending process i simple and completely? Where borrowers to triple digit interest will movies movies receive bad and addresses.

Archive

Archive for January, 2009

Threading Tips and Tricks

January 11th, 2009

 

too-much-threading

Have you ever had trouble designing or debugging multi-threaded applications?

 

Asynchronous programming can be a struggle without a toolbox of techniques and tips to help. Let me show you what I’ve learned to make multi-threading in C# faster to implement and easier to manage!

 

Use the Threads Window

Visual Studio (Standard and up) has a tool for viewing running threads, aptly named the “Threads” window (Start your application in the debugger and then click on Debug->Windows->Threads [or CTRL+D, T]. Break execution to activate the window. From there, you can see which threads are running and minimal information about each one.

threads-window2

The really useful feature about the Threads window is that it allows you to update the call stack window to the thread of your choosing. Just double click on another thread to synchronize the call stack window with the new thread.

thread-menu

Another useful feature is the ability to Freeze and Unfreeze threads without using the Immediate window. Just right click on a given thread to pull up the relevant menu.

Freezing other threads is exceptionally useful if you are trying to step through execution in just one thread and it’s safe to temporarily ignore the others.

Without freezing the other threads, the debugger is likely to move you around from the context of one thread to another while stepping through, wasting your time and energy in the process.

 

Name your threads.

Use the Thread.Name property to assign a descriptive name to each of your threads. For Example:

   1: Thread YearEndProfitReportThread = new Thread(CreateYearEndProfitReport);
   2: YearEndProfitReportThread.Name = "Year End Profits Calculator";
   3: YearEndProfitReportThread.Start();

 

Now, in the Threads window you will be able to see the name you assigned instead of “<No Name>”.

threads-window-named

This is useful while debugging, because of instead of selecting each thread until you find the right one you can jump to exactly the one you need.

 

Leverage the power of C# 3.0

Language specification 3 introduced a few powerful tools such as object initializers and lambda expressions that can apply to threading. These are very powerful tools that obviously need to weighed carefully with readability and maintainability but can dramatically cut down on the amount of code to write.

Note: Parameterless lambdas are only being used here because they are slightly more succinct than using anonymous methods.

Quick and (Very) Dirty Example

   1: (new Thread(() => {
   2:     DoLongRunningWork();
   3:     MessageBox.Show("Long Running Work Finished!");
   4: }) { Name = "Long Running Work Thread",
   5:     Priority = ThreadPriority.BelowNormal }).Start();

 

In only five lines of code, we create a new thread, give it some work to do (via parameterless lambda expression), assign the name and priority (thanks to object initializers) and then trigger it to start. This example assumes reasonable exception handling in the DoLongRunningWork() method and should be wrapped in a try…catch {} block to catch exceptions such as ThreadAbortException (See below for Exception Handling tips).

 

More Practical Example, Hide a Form for X Time

Taking advantage of closures (introduced in 2.0), we can build functions with arguments that are automatically available inside inline lambda statements. Have a look at this example, which hides a form for a certain timespan:

 

   1: private void MakeInvisible(TimeSpan Duration) {
   2:  
   3:     (new System.Threading.Thread(() =>
   4:     {
   5:         try
   6:         {
   7:             this.Invoke(new MethodInvoker(this.Hide));
   8:             System.Threading.Thread.Sleep(Duration);
   9:         }
  10:         catch (ThreadAbortException ThreadAbort)
  11:         {
  12:             //...
  13:         }
  14:         catch (ThreadInterruptedException ThreadInterrupt)
  15:         {
  16:             //...
  17:         }
  18:         finally
  19:         {
  20:             this.Invoke(new MethodInvoker(this.Show));
  21:         }
  22:     }) 
  23:     { 
  24:         Name = "MakeInvisible (" + Duration.ToString() + ")" 
  25:     }
  26:     ).Start();
  27:  
  28: }

 

Using the lambda statement, we are providing the set of instructions to run in our new thread and using property initializers towards the bottom of the function we are setting the thread name. Closures are used with the this keyword and Duration – both of which are passing through to the lambda statement automatically from the host method (MakeInvisible).

Although a bit poor on readability, I think this is a great example of how 3.0 and threading can replace a swath of other (much more complicated) code. To write the same example without the latest language features would take at least a timer and one more method, as well as additional code to wire everything together.

 

Use Airtight Exception Handling

In production applications, it pays you to have the most extensive error handling possible in all of your worker threads. Have a look at the following unsafe code example:

   1: private void UnsafeButton_Click(object sender, EventArgs e)
   2: {
   3:  
   4:     int x = 0;
   5:     int y = 1 / x;
   6:  
   7: }

If you were to start this application outside of the debugger and press the button, at worst you would receive the following dialog box:

divide-by-zero

Bad, but life goes on (via the Continue button). Now, if that same unsafe code is put in a worker thread:

   1: private void UnsafeButton_Click(object sender, EventArgs e)
   2: {
   3:     (new Thread(()=> {
   4:         int x = 0;
   5:         int y = 1 / x;
   6:     })).Start();
   7: }

You are asking for trouble. This is what happens:

stopped-working

The entire application shuts down without details about the exception or a way to continue. (This won’t happen inside the debugger, of course). An alternative to wrapping all of your worker threads in try…catch blocks is to handle the Application.ThreadException Event. This is a quicker way to ensure that your application won’t come to grinding halt when an exception is thrown in a worker thread.

As a final note, be aware that threads are susceptible to the special exceptions ThreadAbortException and ThreadInterruptedException. It’s possible to cancel an initiated abort by handling ThreadAbortException and calling ResetAbort() in the catch block.

Share/Save/Bookmark

C#, Tips and Tricks , , , , , ,

Value Types vs. Reference Types

January 9th, 2009

One area of C# that causes confusion is the difference between value and reference types.

 

Reference Types

 

Let’s talk about reference types for a moment. A common reference type used in .NET is StringBuilder (others include Form, String, All Arrays, Classes, and Delegates). Take a look at this example, do you know what the output will be?

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     StringBuilder X = new StringBuilder("It's Raining In ");
   5:     AppendCityName(ref X);
   6:     Console.WriteLine(X.ToString());
   7: }
   8:  
   9: private void AppendCityName(ref StringBuilder Source) {
  10:  
  11:     Source.Append("Seattle");
  12:  
  13: }

 

The correct answer is “It’s Raining In Seattle”. We pass our new StringBuilder into AppendCityName explicitly by reference and AppendCityName acts on the reference to the original StringBuilder. Nothing too surprising here.

 

Now try this one (I’ve taken away the “ref” keyword – resulting in X being passed By Value), what will the output be?

 

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     StringBuilder X = new StringBuilder("It's Raining In ");
   5:     AppendCityName(X);
   6:     Console.WriteLine(X.ToString());
   7: }
   8:  
   9: private void AppendCityName(StringBuilder Source) {
  10:  
  11:     Source.Append("Seattle");
  12:  
  13: }

 

Did you guess “It’s Raining In Seattle”? The output is identical to the first example.

 

What’s going on here?

Did you expect the output to be “It’s Raining In ”?

StringBuilder is a reference type. That is to say, it lives on the heap (instead of the stack), and the behind-the-scenes value of X in the example above is just the address to the new StringBuilder object created on the heap.

In both examples, only the address to the original StringBuilder on the heap is being passed into the method, and even in the By Value (Second) Example, the StringBuilder data is NOT being copied or moved around at all.

There is a difference between the two, however. In the first example, both X in Main_Load() and Source in AppendCityName() point directly to the same address on the heap. In the second example, Source points to X in Main_Load(), which points to the StringBuilder on the heap.

 

Why is this important?

Passing a reference type by value or by reference is functionally the same 90% of the time. The problem is the remaining 10% of the time. Take the following example:

 

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     StringBuilder X = new StringBuilder("It's Raining In ");
   5:     AppendCityName(ref X);
   6:     Console.WriteLine(X.ToString());
   7: }
   8:  
   9: private void AppendCityName(ref StringBuilder Source) {
  10:  
  11:     Source.Append("Seattle");
  12:     Source = null;
  13:  
  14: }

…which, if you were to execute, unfortunately results in…

exception-01b

Ooops. Because the StringBuilder is passed by reference, AppendCityName() is working with the original reference to the object, and not a copy of the reference. If we were passing the StringBuilder by value, this would have never happened. When in doubt, pass reference types by value and not by reference!

 

Value Types

 

Value types are the complimenting type to reference types. Instead of being stored on the heap, value types are stored on the stack (unless boxed). Integers, Booleans, and Structs are common examples of value types.

When value types are passed By Value, the actual value is copied and there are no references involved. When value types are passed By Reference, the method argument is initialized with the address pointing back to the original value in the calling routine.

 

Here’s an example of passing a value type by reference:

 

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     int TotalDragonCount = 1;
   5:     IncrementDragons(ref TotalDragonCount);
   6:     Console.Write(TotalDragonCount);
   7:  
   8: }
   9:  
  10: private void IncrementDragons(ref int OriginalDragonCount) {
  11:  
  12:     OriginalDragonCount++;
  13:  
  14: }

 

The output is 2. TotalDragonCount is passed into IncrementDragons(), which properly works with a reference to the original value before exiting.

 

Here’s what happens with the same example, but missing the ref keyword (Passing By Value):

 

   1: private void Main_Load(object sender, EventArgs e)
   2: {
   3:  
   4:     int TotalDragonCount = 1;
   5:     IncrementDragons(TotalDragonCount);
   6:     Console.Write(TotalDragonCount);
   7:  
   8: }
   9:  
  10: private void IncrementDragons(int OriginalDragonCount) {
  11:  
  12:     OriginalDragonCount++;
  13:  
  14: }

The output is 1. Notice the difference between value types and reference types? If int was a reference type instead of a value type, this last example would have returned 2.

 

The Takeaway

 

Value types behave very intuitively, but be careful with reference types, especially when passing them By Reference. Know the (subtle) difference between passing value types By Reference and passing reference types By Value (A Value type passed by reference simply points back to the original value type, while a reference type by value creates a copy of the reference (address) inside the method being invoked)

Share/Save/Bookmark

C# , ,