启动带/线程没有委托() [英] Starting a thread with / without delegate()

查看:114
本文介绍了启动带/线程没有委托()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

之间有什么区别:

new Thread(new ThreadStart(SomeFunc))

new Thread( delegate() { SomeFunc();} )

这代码给出我的电脑上奇怪的输出:

This code gives strange outputs on my computer:

public class A
{
    int Num;

    public A(int num)
    {
        Num = num;
    }

    public void DoObj(object obj)
    {
        Console.Write(Num);
    }

    public void Do()
    {
        Console.Write(Num);
    }
}

/////// in void main()

for (int i = 0; i < 10; i++)
{
    (new Thread(new ThreadStart((new A(i)).Do))).Start(); // Line 1
    (new Thread(new ThreadStart(delegate() { (new A(i)).Do(); }))).Start(); // Line 2
    (new Thread(delegate() { (new A(i)).Do(); })).Start(); // Line 3
}

如果只有1号线执行的输出是一样的东西:

If only Line 1 is executed the output is something like:

0 2 3 1 5 6 4 7 8 9

0 2 3 1 5 6 4 7 8 9

这是确定的,但如果2号线或3执行,输出是:

which is ok but if Line 2 or 3 is executed, output is:

3 3 3 5 5 7 7 9 9 10

3 3 3 5 5 7 7 9 9 10

有一些多个号码和一个10这是相当奇怪的是,环不会与数10.什么是运行这背后的把戏?

There are some multiple numbers and a 10 which is quite strange that the loop is never run with the number 10. What is the trick behind these?

感谢。

推荐答案

与委托,您捕获 I

With the delegate, you are capturing i.

不同的是,以新的ThreadStart((新A(I))。做)),要创建 A 在<$ C一个新的实例$ C>与循环>我作为参数。这意味着,在这一点上, i的值拍摄并传送到构造函数。您发送的委托,因此不能创建 A 的,但你实际发送的的委托不要 A 的构造函数的方法。

The difference is that with new ThreadStart((new A(i)).Do)), you are creating a new instance of A in the for loop with i as a parameter. That means that at that point, the value of i is taken and send to the constructor. The delegate you are sending is thus not of the creation of A, but you are actually sending the a delegate of the Do method of the instance of A to the constructor.

然而,委托( ){(新A(I))做()。 })(两者),您发送的参考我的主题。

However, with delegate() { (new A(i)).Do(); }) (both of them), you are sending a reference of i to the thread.

该线程将需要一些时间来启动,同时,在循环下去。由时间 I 在委托(即线程已开始)使用时,循环已经转移到 3 ,这就是你所看到的。这同样适用于第二和第三线程。这三个线程启动,但等到开始线程完成一些工作。然后创建的线程踢(线程1,2和3),他们做他们的工作。在Windows追溯到与循环线程并接着启动线程4和5。

The thread then takes some time to start and meanwhile, the for loop goes on. By the time i is used in the delegate (i.e. the thread has started), the for loop has moved on to 3 and that's what you see. The same goes for the second and third thread. The three threads are started but wait for the starting thread to complete some work. Then the created threads kick in (thread 1, 2 and 3) and they do their work. The Windows goes back to the thread with the for loop and goes on to start thread 4 and 5.

一些阅读材料:

  • http://www.digitallycreated.net/Blog/34/variable-capture-in-c%23-with-anonymous-delegates
  • http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx
  • http://www.albahari.com/threading/#_Passing_Data_to_a_Thread

这篇关于启动带/线程没有委托()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆