I know there are other posts that say you can create a control and then check the InvokeRequired
property to see if the current thread is the main thread or not
You could do it like this:
// Do this when you start your application
static int mainThreadId;
// In Main method:
mainThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
// If called in the non main thread, will return false;
public static bool IsMainThread
{
get { return System.Threading.Thread.CurrentThread.ManagedThreadId == mainThreadId; }
}
EDIT I realized you could do it with reflection too, here is a snippet for that:
public static void CheckForMainThread()
{
if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA &&
!Thread.CurrentThread.IsBackground && !Thread.CurrentThread.IsThreadPoolThread && Thread.CurrentThread.IsAlive)
{
MethodInfo correctEntryMethod = Assembly.GetEntryAssembly().EntryPoint;
StackTrace trace = new StackTrace();
StackFrame[] frames = trace.GetFrames();
for (int i = frames.Length - 1; i >= 0; i--)
{
MethodBase method = frames[i].GetMethod();
if (correctEntryMethod == method)
{
return;
}
}
}
// throw exception, the current thread is not the main thread...
}
If you're using Windows Forms or WPF, you can check to see if SynchronizationContext.Current is not null.
The main thread will get a valid SynchronizationContext set to the current context upon startup in Windows Forms and WPF.
It is much more easy:
static class Program
{
[ThreadStatic]
public static readonly bool IsMainThread = true;
//...
}
And you can use it from any thread:
if(Program.IsMainThread) ...
Here is another option:
if (App.Current.Dispatcher.Thread == System.Threading.Thread.CurrentThread)
{
//we're on the main thread
}
Works for me.
EDIT : Forgot to mention that this works only in WPF. I was searching SO for the WPF case, and I didn't notice that this question is general .NET. Another option for Windows Forms could be
if (Application.OpenForms[0].InvokeRequired)
{
//we're on the main thread
}
Of course, you should first make sure that there is at least one Form
in the application.
In my experience, if you attempt to create a dialog from another thread other than the main thread then windows gets all confused and things start going crazy. I tried to do this once with a status window to show the status of the background thread (as well as many other times someone would toss up a dialog from a background thread - and one that did have a Message Loop) - and Windows just started doing "random" things in the program. I'm pretty sure there was some unsafe handling of something going on. Had issues with clicking on the form and the wrong thread handling the messages...
So, I would never have any UI coming up from Anywhere but the main thread.
However, Why not simply save off the CurrentThread when you start, and compare the ThreadID with the current thread?
-Chert