代码之家  ›  专栏  ›  技术社区  ›  jjxtra

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

  •  34
  • jjxtra  · 技术社区  · 16 年前

    还有其他帖子说你可以在windows窗体中创建一个控件,然后检查 InvokeRequired 属性查看当前线程是否为主线程。

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

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

    有人知道更好的方法吗?这种方式在运行时的未来版本中似乎很容易出错或中断。

    4 回复  |  直到 5 年前
        1
  •  51
  •   jjxtra    15 年前

    你可以这样做:

    // 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; }
    }
    

    编辑

    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...
    }
    
        2
  •  19
  •   Reed Copsey    16 年前

    SynchronizationContext.Current 不为空。

    主线程将获得有效的 SynchronizationContext

        3
  •  13
  •   Peter Duniho    5 年前

    在WPF应用程序中,还有另一个选项:

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

    在Windows窗体应用程序中,只要至少有一个 Form 打开:

    if (Application.OpenForms[0].InvokeRequired)
    {
        //we're on the main thread
    }
    
        4
  •  11
  •   Peter Duniho    5 年前

    这要简单得多:

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

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

    if(Program.IsMainThread) ...
    

    这个 IsMainThread

    因为这片土地 [ThreadStatic] 属性,它在每个线程中都有一个独立的值。初始化器只在访问类型的第一个线程中运行一次,因此该线程中的值是 true false .

        5
  •  2
  •   Chert Pellett    15 年前

    根据我的经验,如果你试图从主线程以外的其他线程创建一个对话框,那么windows会变得混乱,事情开始变得疯狂。我曾经尝试用一个状态窗口来显示后台线程的状态(还有很多次有人会抛出一个来自后台线程的对话框——还有一个确实有消息循环的对话框)——而Windows只是开始在程序中做“随机”的事情。我很肯定发生了一些不安全的事情。单击表单时出现问题,并且处理消息的线程错误。。。

    所以,除了主线程,我永远不会有任何UI出现。

    -燧石