【问题标题】:Using Task with .Net 4.0 vs .Net 4.5?在 .Net 4.0 与 .Net 4.5 中使用任务?
【发布时间】:2012-04-26 18:53:01
【问题描述】:

当我运行这段代码时

      private void button1_Click(object sender, EventArgs e)
    {
        Start(sender, e);
    }

    private void Start(object sender, EventArgs e)
    {
        for (int i = 0; i < 5; i++)
        {
            System.Threading.Tasks.Task.Factory.StartNew(() => dosomething(i));
            Debug.WriteLine("Called " + i);
        }
        Debug.WriteLine("Finished");

    }
    public void dosomething(int i)
    {
        Debug.WriteLine("Enters " + i);
        lock (this)
        {
            Debug.WriteLine("Working " + i);
            Thread.Sleep(100);
        }
        Debug.WriteLine("Done " + i);
    }

.Net 4.0 和 4.5 版的输出不同。在 4.0 数字 5 重复时,我可以看到 i 的原因值在某些任务执行之前被移动到 5,但 4.5 的相同代码显示不同的输出。

(使用 VS 2010 .Net 4.0 运行输出)

Called 0
Called 1
Enters 1
Working 1
Called 2
Called 3
Called 4
Finished
Enters 0
Done 1
Enters 5
Working 0
Working 5
Done 0
**Enters 5
Working 5
Done 5
Enters 5
Done 5
Working 5
Done 5**

但是当我使用 .Net 4.5 (VS 2011 beta) 运行时,结果是,

(使用 VS 2011 beta .Net 4.5 运行输出)

Enters 0
Working 0
Called 0
Called 1
Enters 2
Called 2
Enters 2
Enters 3
Called 3
Called 4
Finished
Done 0
Working 2
Enters 5
Done 2
Working 3
Done 3
Working 5
Done 5
Working 2
Done 2

在 CLR 4.5 下我看不到 Task 所做的更改?谁能告诉我.Net 4.5有什么变化。

【问题讨论】:

    标签: task-parallel-library task .net-4.5 c#-5.0


    【解决方案1】:

    您的代码存在竞争条件。假设循环在任何任务开始之前完成执行。这是完全可能的。

    然后,我将在 所有 个任务中获得 5 的值。这是错误。

    解决方案:将 i 复制到循环局部变量并在任务的 lambda 中使用此局部变量。

    【讨论】:

    • 感谢回复,我同意更改代码 System.Threading.Tasks.Task.Factory.StartNew((object o) => dosomething(i), i);确实可以正常工作,我的问题不是如何使其工作,而是 CLR 4.5 做了哪些更改?
    • @murali 这个问题毫无意义。顺序只是未定义的,并且不需要在同一运行时版本上的不同运行之间保持一致。
    • 我猜新的 CLR 在启动任务时效率更高。因此,(不确定的)顺序发生了变化。顺便说一句,这不是未定义的行为。它是明确定义但不确定的。
    【解决方案2】:

    您的代码有一个race condition。这意味着它可以以不同的方式运行,具体取决于操作的确切顺序。

    而且任何小的改动都可能影响操作的顺序,所以你的代码在不同版本的框架下会有不同的表现也就不足为奇了。实际上,我希望它在为同一版本的 .net 运行多次时表现不同。

    【讨论】:

    • 我不会为订单而烦恼,我只是在看 i 值在 .Net 4.0 的线程之间共享,但不与 .Net 4.5 共享。
    • Start() 中的 i 变量在两种情况下都是共享的,具体发生的情况取决于操作的顺序。
    • 谢谢你的时间......所以,你的意思是 4.5 没有变化,结果是因为操作顺序而不同?我不这么认为,我这样说的理由是什么?如果您观察输出的操作顺序,您只会在短暂暂停后看到值受到影响。而且我已经测试了多次,而且一直都是,顺序不同,但结果和上图一样……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    相关资源
    最近更新 更多