Click here to Skip to main content
15,885,278 members
Articles / Programming Languages / C#
Tip/Trick

Tracking Thread Origins

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
5 Dec 2012CPOL2 min read 7.5K   6  
Grabbing a stack trace for better post-mortem thread exception tracing

Introduction

If you're using threads, a lot of situations may arise where it is useful to know from where the thread was started in order to determine the cause of some issue (exception, inconsistency, <your type of problem here>). Instead of hard-coding this for every situation, a simple extension method can suffice - extend at your leisure with exception handling, etc.

The Code

The code itself is short and sweet:

C#
public static void Threaded(Action ac)
{
    string callingstack = null;
    
    if (GetCallingThreadStackTraces)            
        callingstack = (callingstack = Environment.StackTrace)
            .Substring(callingstack.IndexOf("\r\n"));

    new Thread(() => try { ac() } catch { 
      /*Your error handling code that logs callingstack here*/
    }).Start();
}

Using the Code

  • Simply add the method in any class,
  • Declare GetCallingThreadStackTraces as either a variable or a constant in scope,
  • And implement your error handling code in the catch statement to log to someplace you can access.

Notes and Comments

Notes on GetCallingThreadStackTraces

You'll probably want to disable stack traces in production code (if you're not releasing with debug info). You can also use it to only log the calling thread under certain circumstances (make it a parameter, base it on a parameter, etc.) or to only run on certain machines where the problem is known to occur.

Regarding performance and task

If you're opening up a separate thread for some task that should be waited for / is resource intensive, the performance cost of the stack trace and wrapping code will be a non-factor.

This code is useful for .NET 3.5 and up (if you still develop for XP SP2 targets - an unfortunate reality for many). If you are using Task rather than Thread, you should be able to easily adapt the code for that eventuality.

Personal flavor

Use an extension method instead of manually creating threads everywhere. This behavior (and others) can then be implemented on-demand without rewriting any code. Also, you can wire it up with some short-hand syntax and any additional code that you want for every thread (count the amount of threads created, add performance logging, etc). Example, when wired up to the int class as an extension method:

C#
0.Threaded(() => /*Thread's code here*/);

This might not be in everyone's list of acceptable practices - but works rather well all-round. You can always extend Thread with a static method as well which might be more universally acceptable.

C# 5.0

For C# 5.0+ users, you can add default parameters that log method names and code lines using compiler attributes - this can then provide a single-line stack track for production code where stack traces are not available.

History

2012/11/23 - Posted.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Coderon Technologies
South Africa South Africa
Michiel du Toit is a software developer based in Bloemfontein, South Africa focusing on development using C# and SQL Server (both WinForms and ASP.NET).

Comments and Discussions

 
-- There are no messages in this forum --