如何判断一个线程是否是C#中的主线程

jjx*_*tra 39 .net c# multithreading

我知道还有其他帖子说你可以创建一个控件然后检查InvokeRequired属性以查看当前线程是否是主线程.

问题是你无法知道该控件本身是否是在主线程上创建的.

我使用以下代码来判断一个线程是否是主线程(启动该进程的线程):

if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA ||
    Thread.CurrentThread.ManagedThreadId != 1 ||
    Thread.CurrentThread.IsBackground || Thread.CurrentThread.IsThreadPoolThread)
{
    // not the main thread
}
Run Code Online (Sandbox Code Playgroud)

有谁知道更好的方法?看起来这种方式可能在运行时的未来版本中容易出错或中断.

Zac*_*son 43

你可以这样做:

// 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; }
}
Run Code Online (Sandbox Code Playgroud)

编辑我意识到你也可以用反射来做,这里有一个代码片段:

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...
}
Run Code Online (Sandbox Code Playgroud)


Ree*_*sey 18

如果您使用的是Windows窗体或WPF,则可以检查SynchronizationContext.Current是否为null.

在Windows窗体和WPF中启动时,主线程将获得设置为当前上下文的有效SynchronizationContext.

  • @Jeff:SynchronizationContext是一个非常有用的类 - 它允许你编写"UI-threadsafe"代码,而不需要引用Windows窗体或WPF,这基本上是"未来证明"它.仅供参考 - 在.net 4中,它变得更好:http://reedcopsey.com/2009/11/17/synchronizing-net-4-tasks-with-the-ui-thread/ (3认同)

che*_*ica 12

这是另一种选择:

if (App.Current.Dispatcher.Thread == System.Threading.Thread.CurrentThread)
{
    //we're on the main thread
}
Run Code Online (Sandbox Code Playgroud)

适合我.

编辑:忘了提到这只适用于WPF.我正在搜索WPF案例,我没有注意到这个问题是一般的.NET.Windows Forms的另一个选项可能是

if (Application.OpenForms[0].InvokeRequired)
{
    //we're on the main thread
}
Run Code Online (Sandbox Code Playgroud)

当然,您应首先确保Form应用程序中至少有一个.


Chr*_*hle 7

这要容易得多:

static class Program
{
  [ThreadStatic]
  public static readonly bool IsMainThread = true;

//...
}
Run Code Online (Sandbox Code Playgroud)

您可以从任何线程使用它:

if(Program.IsMainThread) ...
Run Code Online (Sandbox Code Playgroud)