Skip to main content

Multi Threaded NUnit Tests

Recently I needed to reproduce an Entity Framework deadlock issue. The test needed to run in NUnit, and involved firing off two separate threads. The trouble is that in NUnit, exceptions in threads terminate the parent thread without failing the test.

For example, here's a test that starts two threads: the first thread simply logs to the console, while the other thread turfs an exception. What I expected was that this test should fail. However, the test actually passes.

readonly ThreadStart[] delegates = {
    () => {
        Console.WriteLine("Nothing to see here");
    }, () => {
        throw new InvalidOperationException("Blow up");
    }
};

[Test] 
public void SimpleMultiThreading() {
    var threads = delegates.Select(d => new Thread(d)).ToList();
    foreach (var t in threads) {
        t.Start();
    }

    foreach (var t in threads) {
        t.Join();
    }
}

Peter Provost posted an article that describes how to make this test fail. It works by wrapping the thread code in a CrossThreadTestRunner class, that catches exceptions inside the thread, and rethrows the exception outside the thread via a Thread.Join call. Peter also posted another article describing how to use the CrossThreadTestRunner class.

Here's a partial code listing of the CrossThreadTestRunner class

public class CrossThreadTestRunner {
    private ThreadStart userDelegate;
    private Exception lastException;
    
    public CrossThreadTestRunner(ThreadStart userDelegate) {
        this.userDelegate = userDelegate;
    }
    
    public void Run() {
        Thread t = new Thread(new ThreadStart(MultiThreadedWorker));
        t.Start();
        t.Join();

        if (lastException != null) {
            ThrowExceptionPreservingStack(lastException);
        }
    }
    
    private void MultiThreadedWorker() {
        try {
            userDelegate.Invoke();
        }
        catch (Exception e) {
            lastException = e;
        }
    }
}

Peter's solution works if you are only using a single thread per test. If you wanted to run multiple threads in a test, some tweaks are required to the CrossThreadTestRunner class, since the CrossThreadTestRunner.Run method starts the thread, then does a Thread.Join to wait for the thread to complete. The problem with this is that it prevents threads from running in parallel, since Thread.Join blocks the calling thread until the target thread exits.

The change to allow for parallel thread execution is to split up the run method into a Start and a Join method, to mirror the corresponding methods on the Thread class. Here's the modified listing.

public class CrossThreadTestRunner {
    private ThreadStart userDelegate;
    private Exception lastException;
    private Thread thread;
    
    public CrossThreadTestRunner(ThreadStart userDelegate) {
        this.userDelegate = userDelegate;
        this.thread = new Thread(new ThreadStart(MultiThreadedWorker));
    }
    
    public void Start() {
        thread.Start();
    }
    
    public void Join() {
        thread.Join();

        if (lastException != null) {
            ThrowExceptionPreservingStack(lastException);
        }
    }
    
    private void MultiThreadedWorker() {
        try {
            userDelegate.Invoke();
        }
        catch (Exception e) {
            lastException = e;
        }
    }
}

Using the modified version of the CrossThreadTaskRunner, it's now possible to make the original test fail.

readonly ThreadStart[] delegates = {
    () => {
        Console.WriteLine("Nothing to see here");
    }, () => {
        throw new InvalidOperationException("Blow up");
    }
};

[Test] 
public void BetterMultiThreading() {
    var threads = delegates.Select(d => new CrossThreadTestRunner(d)).ToList();
    foreach (var t in threads) {
        t.Start();
    }

    foreach (var t in threads) {
        t.Join();
    }
}

One final tweak to turn this into a green test, is to add the ExpectedExceptionAttribute to the test method, to indicate that the test should fail with the given exception.

The final test looks something like the following

readonly ThreadStart[] delegates = {
    () => {
        Console.WriteLine("Nothing to see here");
    }, () => {
        throw new InvalidOperationException("Blow up");
    }
};

[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void BetterMultiThreading() {
    var threads = delegates.Select(d => new CrossThreadTestRunner(d)).ToList();
    foreach (var t in threads) {
        t.Start();
    }

    foreach (var t in threads) {
        t.Join();
    }
}

Here's the full listing of the modified version of the CrossThreadTestRunner class.

class CrossThreadTestRunner {
        private Exception lastException;
        private readonly Thread thread;
        private readonly ThreadStart start;

        private const string RemoteStackTraceFieldName = "_remoteStackTraceString";
        private static readonly FieldInfo RemoteStackTraceField = typeof(Exception).GetField(RemoteStackTraceFieldName, BindingFlags.Instance | BindingFlags.NonPublic);

        public CrossThreadTestRunner(ThreadStart start) {
            this.start = start;
            this.thread = new Thread(Run);
            this.thread.SetApartmentState(ApartmentState.STA);
        }

        public void Start() {
            lastException = null;
            thread.Start();
        }

        public void Join() {
            thread.Join();

            if (lastException != null) {
                ThrowExceptionPreservingStack(lastException);
            }
        }

        private void Run() {
            try {
                start.Invoke();
            }
            catch (Exception e) {
                lastException = e;
            }
        }

        [ReflectionPermission(SecurityAction.Demand)]
        private static void ThrowExceptionPreservingStack(Exception exception) {
            if (RemoteStackTraceField != null) {
                RemoteStackTraceField.SetValue(exception, exception.StackTrace + Environment.NewLine);
            }
            throw exception;
        }
    }

The code for this article is on GitHub.

Comments

  1. Needed to compose you a very little word to thank you yet again regarding the nice suggestions you’ve contributed here.

    Hadoop Training in Chennai

    ReplyDelete
  2. After reading this web site I am very satisfied simply because this site is providing comprehensive knowledge for you to audience. Thank you to the perform as well as discuss anything incredibly important in my opinion. We loose time waiting for your next article writing in addition to I beg one to get back to pay a visit to our website in
    java training in omr

    java training in annanagar | java training in chennai

    java training in marathahalli | java training in btm layout

    java training in rajaji nagar | java training in jayanagar

    ReplyDelete
  3. Really great post, Thank you for sharing This knowledge.Excellently written article, if only all bloggers offered the same level of content as you, the internet would be a much better place. Please keep it up!
    python training in omr

    python training in annanagar | python training in chennai

    python training in marathahalli | python training in btm layout

    python training in rajaji nagar | python training in jayanagar

    ReplyDelete
  4. Have you been thinking about the power sources and the tiles whom use blocks I wanted to thank you for this great read!! I definitely enjoyed every little bit of it and I have you bookmarked to check out the new stuff you post
    Data Science Training in Chennai
    Data science training in bangalore
    Data science online training
    Data science training in pune
    Data science training in kalyan nagar
    selenium training in chennai

    ReplyDelete
  5. Wow it is really wonderful and awesome thus it is very much useful for me to understand many concepts and helped me a lot. it is really explainable very well and i got more information from your blog.


    rpa training in Chennai | rpa training in velachery

    rpa training in tambaram | rpa training in sholinganallur

    rpa training in Chennai | rpa training in pune

    rpa online training | rpa training in bangalore

    ReplyDelete
  6. Thanks for your informative article, Your post helped me to understand the future and career prospects & Keep on updating your blog with such awesome article.
    python training in annanagar
    python training in chennai
    python training in chennai
    python training in Bangalore

    ReplyDelete
  7. Nice information, valuable and excellent design, as share good stuff with good ideas and concepts, lots of great information and inspiration, both of which I need, thanks to offer such a helpful information here.
    devops online training

    aws online training

    data science with python online training

    data science online training

    rpa online training

    ReplyDelete
  8. Really impressive post. I read it whole and going to share it with my social circules. I enjoyed your article and planning to rewrite it on my own blog.
    data science course malaysia

    ReplyDelete
  9. Thanks for splitting your comprehension with us. It’s really useful to me & I hope it helps the people who in need of this vital information.web design company in velachery

    ReplyDelete
  10. This comment has been removed by the author.

    ReplyDelete
  11. לגמרי פוסט שדורש שיתוף תודה.
    מזנון צף

    ReplyDelete
  12. מזל שנתקלתי בכתבה הזאת. בדיוק בזמן
    מילוי שפתיים

    ReplyDelete
  13. תודה על השיתוף. מחכה לכתבות חדשות.
    הפקת אירועים

    ReplyDelete
  14. אין ספק שזה אחד הנושאים המעניינים. תודה על השיתוף.
    מוצרי תינוקות

    ReplyDelete
  15. Great Information,it has lot for stuff which is informative.I will share the post with my friend
    cat hanging necklace

    ReplyDelete
  16. אין ספק שהפוסט הזה דורש שיתוף. תודה.
    תמונה מודפסת על עץ

    ReplyDelete
  17. תודה על השיתוף. מחכה לכתבות חדשות.
    חברת קידום אתרים

    ReplyDelete
  18. כתיבה מעולה, אהבתי. אשתף עם העוקבים שלי.
    מארזים ליולדת

    ReplyDelete
  19. סגנון כתיבה מרענן, תודה על השיתוף.

    קרקעות להשקעה

    ReplyDelete
  20. הייתי חייבת לפרגן, תודה על השיתוף.
    תמונה על קנבס

    ReplyDelete
  21. I don t have the time at the moment to fully read your site but I have bookmarked it and also add your RSS feeds. I will be back in a day or two. thanks for a great site.
    data science bootcamp malaysia

    ReplyDelete
  22. Really impressive post. I read it whole and going to share it with my social circules. I enjoyed your article and planning to rewrite it on my own blog.

    Cat Doors

    ReplyDelete
  23. very interesting post.this is my first time visit here.i found so many interesting stuff in your blog especially its discussion..thanks for the post!
    Data Science Course in Hyderabad | Data Science Training in Hyderabad

    ReplyDelete
  24. Nice service there are just few who are providing this service great job.


    Bastion Balance Korea

    ReplyDelete
  25. Amazing post found to be very impressive while going through this post. Lots of appreciation to the blogger who took an initiative to write this particular blog. Thanks for sharing and keep posting such an informative content.

    360DigiTMG Cyber Security Course

    ReplyDelete
  26. Really nice and interesting post. I was looking for this kind of information and enjoyed reading this one. Keep posting. Thanks for sharing.
    visit here

    ReplyDelete
  27. מרתק כמה שלא הבנתי כלום עד שקראתי את המאמר הנפלא הזה

    בניית בריכת שחייה מבטון

    ReplyDelete

  28. Additionally, this is an excellent article which I truly like studying. It's not everyday I have the option to see something similar to this.
    Data Science Training Institute in Bangalore

    ReplyDelete
  29. Some time we never feel what we have done but for other that is big achievement


    Garage Door Repair Strathmore

    ReplyDelete
  30. Truly incredible blog found to be very impressive due to which the learners who ever go through it will try to explore themselves with the content to develop the skills to an extreme level. Eventually, thanking the blogger to come up with such an phenomenal content. Hope you arrive with the similar content in future as well.

    Digital Marketing training

    ReplyDelete
  31. It doesn't look too old, what so ever nice location.


    pittsburgh garage door repair

    ReplyDelete
  32. Good topic, this is going to help a lot of people get the whole concept


    fridge repair mississauga

    ReplyDelete
  33. This is a great article thanks for sharing this informative information.
    garage door repair strathmore

    ReplyDelete
  34. Seo company in Varanasi, India : Best SEO Companies in Varanasi, India: Hire Kashi Digital Agency, best SEO Agency in varanasi, india, who Can Boost Your SEO Ranking, guaranteed SEO Services; Free SEO Analysis.

    Best Website Designing company in Varanasi, India : Web Design Companies in varanasi We design amazing website designing, development and maintenance services running from start-ups to the huge players


    Wordpress Development Company Varanasi, India : Wordpress development Company In varanasi, india: Kashi Digital Agency is one of the Best wordpress developer companies in varanasi, india. Ranked among the Top website designing agencies in varanasi, india. wordpress website designing Company.

    E-commerce Website designing company varanasi, India : Ecommerce website designing company in Varanasi, India: Kashi Digital Agency is one of the Best Shopping Ecommerce website designing agency in Varanasi, India, which provides you the right services.

    ReplyDelete
  35. yes it happens with me as well. we feel the difference, convince and comfort. but how ever we are not simple free of worries as these old people were.nice article.


    garage door cable repair ottawa

    ReplyDelete
  36. Great article nicely presented and informative article.


    garage door moving slow

    ReplyDelete
  37. "I would like to say that, your blog is very nice, informative and amazing. Thanks for sharing your blog with us."
    Refrigerator Repair Service in Delhi

    ReplyDelete
  38. מאמר מצוין נהניתי מכל רגע של קריאה

    מערכות אינטרקום

    ReplyDelete
  39. Great article nicely presented and informative article.


    legiongaragedoors.ca

    ReplyDelete
  40. Cool stuff you have and you keep overhaul every one of us
    data science in malaysia

    ReplyDelete
  41. Incredibly conventional blog and articles. I am realy very happy to visit your blog. Directly I am found which I truly need. Thankful to you and keeping it together for your new post.
    data science courses in noida

    ReplyDelete
  42. Nice and very informative blog, glad to learn something through you.
    data analytics course delhi

    ReplyDelete
  43. Learn Amazon Web Services for making your career towards a sky-high with Infycle Technologies. Infycle Technologies is the best AWS training center in Chennai, providing courses for the AWS Training in Chennai in 200% hands-on practical training with professional trainers in the domain. Apart from the coaching, the placement interviews will be arranged for the students, so that they can set their career without any struggle. Of all that, 100% placement assurance will be given here. To have the best career, call 7502633633 to Infycle Technologies and grab a free demo to know more.Best AWS Training in Chennai

    ReplyDelete
  44. I just finished reading your book Doe's Ways and wanted to tell you how much I enjoyed it.
    360DigiTMG hrdf contribution

    ReplyDelete
  45. Very interesting and thanks for sharing such a good blog. keep sharing.
    best machine learning course in aurangabad

    ReplyDelete
  46. This post is very simple to read and appreciate without leaving any details out. Great work!
    artificial intelligence course in pune

    ReplyDelete
  47. I am reading your post from the beginning, it was so interesting to read & I feel thanks to you for posting such a good blog, keep updates regularly.I want to share about
    machine learning training in aurangabad

    ReplyDelete
  48. I am reading your post from the beginning, it was so interesting to read & I feel thanks to you for posting such a good blog, keep updates regularly.I want to share about
    machine learning training in aurangabad

    ReplyDelete
  49. Wonderful article. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article. This article resolved my all queries.

    DevOps Training Institute in Pune

    ReplyDelete
  50. Wow, cool post. I'd like to write like this too - taking time and real hard work to make a great article. but I put things off too much and never seem to get started pinoylambingan first drama site to release the latest episodes of All new Dramas

    ReplyDelete
  51. Really Nice Information It's Very Helpful All courses Checkout Here.
    data scientist courses aurangabad

    ReplyDelete
  52. No.1 AWS Training Institute in Chennai | Infycle Technologies

    Description:
    Study Amazon Web Services for making your career as a shining sun with Infycle Technologies. Infycle Technologies is the best AWS training institute in Chennai, providing complete hands-on practical training of professional specialists in the field. In addition to that, it also offers numerous programming language tutors in the software industry such as Oracle, Python, Big Dat, Hadoop, etc. Once after the training, interviews will be arranged for the candidates, so that, they can set their career without any struggle. Of all that, 200% placement assurance will be given here. To have the best career, call 7502633633 to Infycle Technologies and grab a free demo to know more.

    Best training in Chennai

    ReplyDelete
  53. Learn Java Course in Chennai for making your career as a shining sun with Infycle Technologies. Infycle Technologies is the best Java training institute in Chennai, providing complete hands-on practical training of professional specialists in the field. It also offers numerous programming language tutors in the software industry such as Python, AWS, Hadoop, etc. Once after the training, interviews will be arranged for the candidates to set their career without any struggle. Of all that, 200% placement assurance will be given here. To have the best job, call 7502633633 to Infycle Technologies and grab a free demo to know more.

    best training institute in chennai

    ReplyDelete
  54. It is what I was searching for is really informative. It is a significant and useful article for us. Thankful to you for sharing an article like this. top mba college in Lucknow

    ReplyDelete
  55. Your article is good to understand, are you interested in doors and windows? Our service is helpful to you.
    Modern aluminium doors in chennai
    Best Aluminium Windows in Chennai
    upvc ventilator window in Chennai

    ReplyDelete
  56. You've posted a very informative post here. This article provided me with some useful knowledge. Thank you for sharing that. Keep up the good work. Best MBA colleges in Kerala

    ReplyDelete
  57. I admire this article for the well-researched content and excellent wording. Read more info about Devops Support Company. I got so involved in this material that I couldn’t stop reading. I am impressed with your work and skill. Thank you so much.

    ReplyDelete
  58. This post is so interactive and informative.keep update more information...
    hadoop training in tambaram
    Big data training in chennai

    ReplyDelete
  59. Web Solution Centre is a leading Website Development company in Delhi, we are Expert in custom website development, eCommerce website designing, Android & iPhone apps development Since 2008.

    ReplyDelete
  60. Nice post. Please Look, we are the garage door repair in Los Angeles
    (service provider).
    Thank you

    ReplyDelete

  61. If the garage door repair in Chicago won't open or close, begin with these garage door troubleshooting steps: Make sure the opener is plugged in and the garage circuit breaker is in the correct place. Thankyou for share this useful information.

    ReplyDelete
  62. Need Tata Xenon Spare Parts? Look no further than our online store, where you'll find everything you need for a hassle-free shopping experience.

    ReplyDelete
  63. This comment has been removed by the author.

    ReplyDelete
  64. I find it amazing how ancient civilizations were aware of the healing properties of crystals long before modern science confirmed their benefits. There's so much ancient wisdom to explore in this area. Buy Healing Crystals

    ReplyDelete
  65. I am so grateful to have found this post. It is so well-explained. contact us

    ReplyDelete
  66. This is an incredibly insightful piece. Loved how you delved deep into the topic! https://www.windowcleanerscoquitlam.com

    ReplyDelete

Post a Comment

Popular posts from this blog

Basic Web Performance Testing With JMeter and Gatling

Introduction In this post I'll give a quick way to get some basic web performance metrics using both JMeter and Gatling . JMeter is a well known, open source, Java based tool for performance testing. It has a lot of features, and can be a little confusing at first. Scripts (aka Test Plans), are XML documents, edited using the JMeter GUI.  There are lots of options, supports a wide variety of protocols, and produces some OK looking graphs and reports. Gatling is a lesser known tool, but I really like it. It's a Scala based tool, with scripts written in a nice DSL. While the scripts require some basic Scala, they are fairly easy to understand and modify. The output is a nice looking, interactive, HTML page. Metrics   Below are the basic metrics gathered by both JMeter and Gatling . If you are just starting performance testing, these might be a good starting point . Response Time – Difference between time when request was sent and time when response has been fully rec

Generating Java Mixed Mode Flame Graphs

Overview I've seen Brendan Gregg's talk on generating mixed-mode flame graphs  and I wanted to reproduce those flamegraphs for myself. Setting up the tools is a little bit of work, so I wanted to capture those steps. Check out the Java in Flames post on the Netflix blog for more information. I've created github repo ( github.com/jerometerry/perf )  that contains the scripts used to get this going, including a Vagrantfile, and JMeter Test Plan. Here's a flame graph I generated while applying load (via JMeter) to the basic arithmetic Tomcat sample application. All the green stacks are Java code, red stacks are kernel code, and yellow stacks are C++ code. The big green pile on the right is all the Tomcat Java code that's being run. Tools Here's the technologies I used (I'm writing this on a Mac). VirtualBox 5.1.12 Vagrant 1.9.1 bento/ubuntu-16.04 (kernel 4.4.0-38) Tomcat 7.0.68 JMeter 3.1 OpenJDK 8 1.8.111 linux-tools-4.4.0-38 linux-to