Article: Asynchronous operations run on ThreadPool threads

Home Page


Consultancy

  • Service Vouchers
  • Escrow Service

Shop



Programming
  • Articles
  • Tools
  • Links

Search

 

Contact

 

Chess Puzzles




DWHS

Valid XHTML 1.0 Transitional
Valid CSS!
Mobile-friendly!

A little experiment to verify most asynchronous operations do execute on some ThreadPool thread.

category 'experiment', language C#, created 22-Jun-2009, version V1.0, by Luc Pattyn


License: The author hereby grants you a worldwide, non-exclusive license to use and redistribute the files and the source code in the article in any way you see fit, provided you keep the copyright notice in place; when code modifications are applied, the notice must reflect that. The author retains copyright to the article, you may not republish or otherwise make available the article, in whole or in part, without the prior written consent of the author.

Disclaimer: This work is provided “as is”, without any express or implied warranties or conditions or guarantees. You, the user, assume all risk in its use. In no event will the author be liable to you on any legal theory for any special, incidental, consequential, punitive or exemplary damages arising out of this license or the use of the work or otherwise.


The .NET Framework offers lots of classes that perform some operations asynchronously, i.e. they organize something to happen and don't wait for the outcome.

When asynchronous operations need to execute some user code, they need a thread to execute it; it typically can't be the main thread since that is either busy doing other things, and/or is kept free for servicing the GUI. What the MSDN documentation does not tell us clearly is such operations typically get executed on ThreadPool threads.

The AsyncOnThreadPool experiment provides a simple means to observe how those asynchronous operations are carried out.

 

Asynchronous actions on ThreadPool

The experiment

The test application basically has a button handler that causes several asynchronous actions to be launched; all activity gets logged in the ListBox while showing the actual time (a StopWatch value since app start) and the thread ID of the executing thread, coded as follows:

  • green, and marked [GUI], when it is the main aka GUI thread;
  • black, and marked [Pxx], when it is a ThreadPool thread with ID=xx;
  • red, and marked [ xx], when it is a general thread with ID=xx.

An optional Thread.Sleep(500) is added to the asynchronous code, allowing to modify the availability of some of the threads when the next asynchronous action might occur.

The project files are available here.

Observations

  • All asynchronous operations are executed on ThreadPool threads, except for some documented events that execute on the main or "GUI" thread:
    • System.Windows.Forms.Timer.Tick
    • System.ComponentModel.BackgroundWorker.ProgressChanged
    • System.ComponentModel.BackgroundWorker.RunWorkerCompleted
  • Periodic events may hop from one thread to another; e.g. timer events may execute on a different ThreadPool thread each time.
  • Dedicated events seem to reuse the same thread all the time; e.g. SerialPort.DataReceived and Process.OutputDataReceived. Note that this is not guaranteed by the documentation.

Other points of interest

  • The test application uses a ListBox for logging test results; DrawMode.OwnerDrawFixed has been selected, so we could have the DrawItem event paint text lines using different colors.
  • A StopWatch has been used instead of reading DateTime.Now in order to get an actual timing reolution of one millisecond.


Perceler

Copyright © 2012, Luc Pattyn

Last Modified 02-Sep-2013