Search code examples
multithreadingsilverlight-4.0autoresetevent

How do I find if the current executed code is on the UI thread?


I am developing a silverlight application and I have a method that should throw an exception if it's ran on the UI thread since it uses AutoResetEvent.WaitOne() without timeout which causes the UI thread to freeze.
How do I detect if the current thread is the UI thread?

EDIT:
Note that this method resides in a class library and not in a UI component.


Solution

  • You can check if you are in the main UI thread by using Application.Current.Dispatcher (use the CheckAccess() function).

    Notice i said main UI thread - this is important, as any thread can have a dispatcher associated with it*, and you can have more than one UI thread. To be more accurate, your question should be

    How do I find if the current executed code is a UI thread?

    AFAIK this may not be possible with any certainty, as the only real discernable difference (that i have seen) between a background (thread pool) thread and a UI thread is their ApartmentState - UI threads are STA, and the threads available in the thread pool are MTA. This doesn't mean that a STA thread is a UI thread though. (I would be glad for someone to chip in with something definitive here). Maybe your solution is to look at it the other way - ensure that the AutoResetEvent.WaitOne() calls are only done on threads that are MTA.

    *just try executing the code this.Dispatcher.CheckAccess() on a background thread and see what happens....

    Edit:

    thanks to @drow for pointing out that this should be Silverlight... duh. I will leave the answer above untouched as it is still applicable for WPF. As mentioned by @drow, there is no way to access the ApartmentState of the thread in Silverlight, and the Dispatcher is not available when using System.Threading.Thread.CurrentThread.

    So as another option you can check whether Deployment.Current.Dispatcher.CheckAccess() returns false, if it is then you are on a background thread (i.e. not the main UI thread). I did test this, and it works nicely.