Windows 我能确保我写的代码总是在同一个线程中执行吗?

Windows 我能确保我写的代码总是在同一个线程中执行吗?,windows,multithreading,com,Windows,Multithreading,Com,我通常在单线程应用程序上工作,通常从来没有真正费心处理线程。我对事物如何工作的理解——当然,这可能是错误的——是,只要我们总是处理单线程代码(即,没有分叉或类似的东西),它就总是在同一个线程中执行 这个假设正确吗?我有一个模糊的想法,UI库/框架可能会产生自己的线程来处理GUI内容(这说明Windows任务管理器告诉我我的“单线程”应用程序实际上运行在10个线程上),但我猜这不会影响我吧 这如何适用于COM?例如,如果我要在代码中创建COM组件的实例;COM组件将一些信息写入基于线程的位置(例如

我通常在单线程应用程序上工作,通常从来没有真正费心处理线程。我对事物如何工作的理解——当然,这可能是错误的——是,只要我们总是处理单线程代码(即,没有分叉或类似的东西),它就总是在同一个线程中执行

这个假设正确吗?我有一个模糊的想法,UI库/框架可能会产生自己的线程来处理GUI内容(这说明Windows任务管理器告诉我我的“单线程”应用程序实际上运行在10个线程上),但我猜这不会影响我吧

这如何适用于COM?例如,如果我要在代码中创建COM组件的实例;COM组件将一些信息写入基于线程的位置(例如使用
System.Threading.thread.GetData
),我的应用程序是否能够获取这些信息

总而言之:

  • 在单线程代码中,我是否可以确保存储在基于线程的位置中的任何内容都可以从代码中的任何其他位置检索

  • 如果单线程代码要创建一个COM组件的实例,该实例将一些信息存储在基于线程的位置,那么它是否可以从其他任何地方进行类似的检索


  • UI通常有相反的约束(遗憾的是):它是单线程的,所有事情都必须在该线程上发生

    检查您是否始终处于同一线程(例如,函数)的最简单方法是将整数变量设置为-1,并使用类似(例如,您处于C#)的检查函数:

    void资产单线程()
    {
    如果(m_ThreadId<0)m_ThreadId=Thread.CurrentThread.ManagedThreadId;
    Assert(m_ThreadId==Thread.CurrentThread.ManagedThreadId);
    }
    
    也就是说:

    我真的不明白问题1。如果您的目的是拥有一个全局范围,为什么要存储在基于线程的位置

    关于第二个问题,大多数COM代码运行在一个线程上,并且通常运行在UI消息处理所在的线程上——这是因为大多数COM代码设计为与VB6(单线程)兼容


    您的程序大约有10个线程的原因是,Windows(如果您使用它的某些功能,如完成端口或某种计时器)和CLR(例如GC或某些类型的计时器)都可能在您的进程空间中创建线程(从技术上讲,任何具有足够特权的程序也可以).

    考虑在主线程中运行单个数据存储类的模型,所有线程都可以读写它们的实例变量。这将避免访问整个商店中的线程时可能出现的许多问题

    简单的想法,直到你达到线程有趣的部分。并发和同步;简单地说,如果有两个线程希望同时读取和写入数据存储中的同一变量,那么就有问题了

    Java通过允许您声明一个已同步的变量或方法来处理这个问题,一次只允许一个线程访问


    我相信有些.NET对象上定义了锁和同步方法,但我只知道这些。

    你说得对,第一个问题相当愚蠢。本质上,我想确保我的代码始终在同一个线程上运行。理论上(读:“通常”)如果不显式地编写多线程代码,那么所有内容都将在同一线程中运行,从UI开始,以计时器事件结束。可能会有在其他线程上生成的计时器,但通常必须显式指定。
    void AssertSingleThread()
    {
       if (m_ThreadId < 0) m_ThreadId = Thread.CurrentThread.ManagedThreadId;
       Debug.Assert(m_ThreadId == Thread.CurrentThread.ManagedThreadId);
    }