none
C#中有没有C++中的用户界面线程,是什么?谢谢! RRS feed

  • 问题

  • C#中有没有C++中的用户界面线程,是什么?

    (附:窗体线程是用户界面线程,但用户界面线程不只是窗体线程。)

    我想创建用户界面子线程,使用其消息队列和一直运行的特点,这样就不用自己去创建维护消息队列和线程了,不知道C#中是否已经取消用户界面线程了,只有work线程了。

    那位牛人有空解答一下。谢谢!

    • 已编辑 yjw 2010年3月30日 7:39
    2010年3月30日 1:37

答案

  • 有啊,对于Windows 应用程序来说,界面线程通常意义上就是一个进程中的0号线程。 也就是第一个被创建、运行的那个线程。

    打开你应用程序的Program.cs 文件,里面应该有一个Main 函数,运行这个Main 函数的那个线程一般就是界面线程。通常里面都有一行代码:

    Application.Run(new Form1());

    这一行代码首先会在内存中new 一个Form1 类型的窗体,然后显示它。最后进入一个消息循环,等待用户发送消息。Form1 的InitializeComponents 函数中就含有创建界面控件的代码,因此这些控件也就自然地运行在界面线程中了。 除此以外显示、隐式创建的线程都不是界面线程了。

    • 已建议为答案 mazhou 2010年3月30日 8:35
    • 已标记为答案 mldarkMember 2010年4月3日 14:56
    2010年3月30日 5:56
  • Windows 的控件遵循谁创建谁使用的原则。主要是因为控件都是由窗体构成的,而窗体资源是用Handle 来表示的。Handle 这个东东无法跨线程来操作和使用(虽然有时候你那么做了,但是是极不安全的)。 跨线程操作Handle 一般都需要用Windows API DuplicateHandle 生成出另外一个Handle 来标识同一个对象,给当前线程使用。因为这些可见的控件都是由0号线程创建出来的,因此,只有0号线程才可以操纵他们。

    原则上说,一个后台线程偷偷地创建了一个控件,并不在UI上显示,而且这个控件仅被这个后台线程所使用,应该也是安全的。但这么做没啥意义。

    • 已建议为答案 mazhou 2010年3月31日 9:57
    • 已标记为答案 mldarkMember 2010年4月3日 14:56
    2010年3月31日 2:54
  • C#所用的一系列API被称为winform,所有的GUI控件都继承于System.Windows.Form.Control 类。

    Control类已经封装好了消息队列。你可以看这个函数:

    protected virtual void WndProc(
        ref Message m
    ) 

    这个消息队列是在主线程上被执行的,也就是你所说的用户界面线程。

    举个很简单的例子,创建一个button,然后button_click事件里面 Sleep 个 10 秒。当用户按那个 button 的时候,整个用户界面会失去响应的。也就是,button_click那个消息是被放在了主线程或者用户界面线程上被执行的。

     

     


    MCPD (Windows & Web)
    2010年4月2日 8:35

全部回复

  • 一般窗体就是用户界面线程吧
    family as water
    2010年3月30日 1:51
  • 感觉不是,BackgroundWorker好像没有消息队列,不能异步调用。
    2010年3月30日 1:54
  • 有啊,对于Windows 应用程序来说,界面线程通常意义上就是一个进程中的0号线程。 也就是第一个被创建、运行的那个线程。

    打开你应用程序的Program.cs 文件,里面应该有一个Main 函数,运行这个Main 函数的那个线程一般就是界面线程。通常里面都有一行代码:

    Application.Run(new Form1());

    这一行代码首先会在内存中new 一个Form1 类型的窗体,然后显示它。最后进入一个消息循环,等待用户发送消息。Form1 的InitializeComponents 函数中就含有创建界面控件的代码,因此这些控件也就自然地运行在界面线程中了。 除此以外显示、隐式创建的线程都不是界面线程了。

    • 已建议为答案 mazhou 2010年3月30日 8:35
    • 已标记为答案 mldarkMember 2010年4月3日 14:56
    2010年3月30日 5:56
  • ”除此以外显示、隐式创建的线程都不是界面线程了“,那就是说没办法创建没有窗体的UI子线程了?
    2010年3月30日 7:40
  • ”除此以外显示、隐式创建的线程都不是界面线程了“,那就是说没办法创建没有窗体的UI子线程了?


    应该是不能。.NET 中默认只有一个主 UI 线程,在调试的时候,通过 Output Window 可以看到的线程中的第一个一般就是。

    BackgroundWorker 不是用消息队列实现的,它用线程池的,也可以异步调用。

    也不一定非要创建 UI 子线程。New 一个 Thread 然后用 Invoke/BeginInvoke 就可以跨线程同步/异步操作 UI 线程对象了。


    Mark Zhou
    2010年3月30日 8:39
  • Windows 的控件遵循谁创建谁使用的原则。主要是因为控件都是由窗体构成的,而窗体资源是用Handle 来表示的。Handle 这个东东无法跨线程来操作和使用(虽然有时候你那么做了,但是是极不安全的)。 跨线程操作Handle 一般都需要用Windows API DuplicateHandle 生成出另外一个Handle 来标识同一个对象,给当前线程使用。因为这些可见的控件都是由0号线程创建出来的,因此,只有0号线程才可以操纵他们。

    原则上说,一个后台线程偷偷地创建了一个控件,并不在UI上显示,而且这个控件仅被这个后台线程所使用,应该也是安全的。但这么做没啥意义。

    • 已建议为答案 mazhou 2010年3月31日 9:57
    • 已标记为答案 mldarkMember 2010年4月3日 14:56
    2010年3月31日 2:54
  • 创建一个后台线程来显示一个新form也许可行,不过这么做的意义似乎不大,毕竟显示器只有一个……
    霸王
    2010年3月31日 6:21
  • C#所用的一系列API被称为winform,所有的GUI控件都继承于System.Windows.Form.Control 类。

    Control类已经封装好了消息队列。你可以看这个函数:

    protected virtual void WndProc(
        ref Message m
    ) 

    这个消息队列是在主线程上被执行的,也就是你所说的用户界面线程。

    举个很简单的例子,创建一个button,然后button_click事件里面 Sleep 个 10 秒。当用户按那个 button 的时候,整个用户界面会失去响应的。也就是,button_click那个消息是被放在了主线程或者用户界面线程上被执行的。

     

     


    MCPD (Windows & Web)
    2010年4月2日 8:35