dotnet Exception Handling

.NET Exceptions – InvalidAsynchronousStateException

As we approach the end of our in-depth .NET Exception Handling series, today we’ll be taking a closer look at the System.ComponentModel.InvalidAsynchronousStateException. An InvalidAsynchronousStateException is a complex exception that occurs when an operation is attempted for which its target thread no longer exists, or has no message loop.

Throughout this article we’ll explore the InvalidAsynchronousStateException by looking first at where it sits in the larger .NET exception hierarchy. Then, we’ll take a look at some functional sample code that shows how you might run into an InvalidAsynchronousStateException in your own multi-threaded application if you aren’t careful as a developer. Let’s get started!

The Technical Rundown

All .NET exceptions are derived classes of the System.Exception base class, or derived from another inherited class therein. The full exception hierarchy of this error is:

Full Code Sample

Below is the full code sample we’ll be using in this article. It can be copied and pasted if you’d like to play with the code yourself and see how everything works.

When Should You Use It?

As mentioned, the appearance of an InvalidAsynchronousStateException indicates a problem with threading within your application. Usually, it indicates that an operation was attempted within a thread that no longer exists. Since multi-threading is such a broad and complex topic, it’s well beyond the scope of this tiny article, so we’ll just cover the basics in our own code example. Just keep in mind that this technique is by no means representative of the only way to accomplish multi-threading.

For our example we’re creating a Windows Form Application (i.e. an application with user interface elements, as opposed to the normal console-based applications we usually create). There’s no need to include all the code, but here we can see that our main Program.Main() method includes a call to our custom DualThreadTester() class:

The DuelThreadTester class is intended to create a new foreground and background thread, and perform some basic iteration a few times a second with output. In addition, we want to create a new UI element (a background Form, in this case), and be able to perform an InvalidAsynchronousStateExceptionocation within this UI control to invoke a specific method. This will make more sense in code, so let’s start with the structure, including our single _backgroundForm property, along with the BackgroundThreadDelegate(string message) delegate, and the BackgroundThreadDelegateMethod(string message) method:

We’ll be InvalidAsynchronousStateExceptionoking this delegate and method from our _backgroundForm control, so it’s important we establish these first.

Next comes the primary looping method of IterationTest():

Since this method is used by both our foreground and background threads, we start by checking if the current thread is background, in which case we instantiate a new BackgroundForm control and Show() it.

From there, we perform a simple iterative loop 10 times. During each loop, since our foreground thread will execute slightly before our background thread (in most cases), we check if _backgroundForm exists within the foreground thread iteration. If it exists, we use the thread safe method of calling an InvalidAsynchronousStateExceptionoke() method on our _backgroundForm control. The InvalidAsynchronousStateExceptionokeRequired property simply checks if the current thread differs from the thread that created the _backgroundForm control. If so (which is always the case here), we explicitly call _backgroundForm.Invoke(...) and use our BackgroundThreadDelegate delegate to create a simple output message. If InvalidAsynchronousStateExceptionokeRequired is false, we can just directly change the control (in this case, by changing the background color to red).

Regardless of which thread is iterating, we output the thread name and the current iteration count to the log, then pause for a quarter of a second before repeating. Once all iterations complete, we output that the thread has finished iteration.

Overall, it’s not too complicated, so let’s create our actual threads in the DualThreadTester constructor:

As the comments explain, we’re simply instantiating two new threads, naming them and setting the appropriate IsBackground property, then starting them up. This will cause both threads to begin execution of the IterationTest method. Let’s execute this code and see what happens.

There we go. As we can see from the output, our foreground thread only began a single iteration, then reached the _backgroundForm.Invoke(new BackgroundThreadDelegate(BackgroundThreadDelegateMethod),count); statement, which blocks the foreground thread from executing until this invocation can be executed. Thus, foreground waited the 2.5 seconds until the background thread finished its iterations, then the _backgroundForm.Invoke(...) method call was executed. However, as indicated by the InvalidAsynchronousStateException we see, this operation could no longer complete because the background thread closed itself out once it finished its iterations.

To get the most out of your own applications and to fully manage any and all .NET Exceptions, check out the Airbrake .NET Bug Handler, offering real-time alerts and instantaneous insight into what went wrong with your .NET code, along with built-in support for a variety of popular development integrations including: JIRA, GitHub, Bitbucket, and much more.