简体   繁体   English

如何在新线程中强制执行

[英]How to force execution in new thread

I have such code in my app: 我的应用程式中有这样的程式码:

var t = new Thread(new ThreadStart(new Action(SomeClass.SomeMethod)));
t.Start();
...
t.Join();

but as I understand, compiler does some optimization and run SomeMethod in the same thread as main code. 但是据我了解,编译器进行了一些优化,并在与主代码相同的线程中运行SomeMethod。 I check this by setting different Names of the thread in t and Thread.CurrentThread. 我通过在t和Thread.CurrentThread中设置不同的线程名称来进行检查。 How I can create and run thread to be sure it's new thread. 我如何创建和运行线程以确保它是新线程。

The compiler will not optimize your code in that manner. 编译器不会以这种方式优化您的代码。 The code will be run in a new .NET thread. 该代码将在新的.NET线程中运行。 There must have been an error in the way you made your observations. 您进行观察的方式一定存在错误。

Note that .NET threads aren't necessarily equivalent to OS threads: 请注意,.NET线程不一定等效于OS线程:

An operating-system ThreadId has no fixed relationship to a managed thread, because an unmanaged host can control the relationship between managed and unmanaged threads. 操作系统ThreadId与托管线程没有固定的关系,因为非托管主机可以控制托管线程和非托管线程之间的关系。 Specifically, a sophisticated host can use the CLR Hosting API to schedule many managed threads against the same operating system thread, or to move a managed thread between different operating system threads. 具体而言,复杂的主机可以使用CLR Hosting API来针对同一操作系统线程调度许多托管线程,或者在不同的操作系统线程之间移动托管线程。

You could in theory see two managed threads with the same Windows thread ID, but the Thread.Name property will still be different (assuming you initally set the names to two different values). 从理论上讲,您可以看到两个具有相同Windows线程ID的托管线程,但是Thread.Name属性仍然会有所不同(假设您最初将名称设置为两个不同的值)。

If you could post the code you used where you observed something being run in the wrong thread it might be possible to discover what error you have made. 如果您可以将所用的代码发布到观察到错误线程中正在运行的代码的位置,则有可能发现您犯了什么错误。

I think you have made an error in your code. 我认为您的代码有误。 Try this: 尝试这个:

Thread.CurrentThread.Name = "main";

var t = new Thread(new ThreadStart(new Action(SomeClass.SomeMethod))); 
t.Name = "worker";

t.Start(); 
// ... 
t.Join(); 

Be aware that Thread.Name is a write-once property. 请注意, Thread.Name是一次写入属性。 It is therefore a bad idea to name thread pool threads! 因此,命名线程池线程是一个坏主意!

As I understand it, if you tell a program to run a task in a new thread, that's exactly what will happen. 据我了解,如果您告诉程序在新线程中运行任务,那将是正确的。 Those two threads may end up running on the same core (because your calling thread may not do much except wait for the other thread to complete), but you will have two different memory spaces and execution pointers in your process. 这两个线程可能最终在同一内核上运行(因为您的调用线程除了等待另一个线程完成之外可能不会做很多事情),但是您的进程中将有两个不同的内存空间和执行指针。

An easy way to prove it is to open up task manager, set a breakpoint in SomeMethod, check the thread count of VS (devenv.exe) in the Processes tab, then hit the Debug button to launch your program. 证明它的一种简单方法是打开任务管理器,在SomeMethod中设置一个断点,在“进程”选项卡中检查VS(devenv.exe)的线程数,然后单击“调试”按钮以启动程序。 When it hits the breakpoint, examine the thread count again; 当它达到断点时,再次检查线程数; you'll have two new threads, one for the main program execution flow and one for your worker thread. 您将有两个新线程,一个用于主程序执行流程,另一个用于您的工作线程。 There may be one more for the attached debugger. 附带的调试器可能还会有一个。

Why not use the Task library? 为什么不使用任务库? (if you use .NET 4.0) (如果使用.NET 4.0)

Task task = Task.Factory.StartNew(() => 
             {
                 // your code here, this will be executed in a Task thread
             });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM