【问题标题】:Lambda expressions with multithreading in C#在 C# 中具有多线程的 Lambda 表达式
【发布时间】:2012-02-23 12:01:05
【问题描述】:

我试图了解为什么这个程序不起作用

预期输出:随机顺序的数字 0-19 我运行时得到的结果:一些数字重复,有时会打印 20。

请帮忙。我尝试在 DoSomething() 中使用 lock(obj) 但没有帮助。

程序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication2
{
    public delegate void callbackDelegate(int x);
    class Program
    {
        void processCallback(int x)
        {
            Console.WriteLine("IN callback: The value I got is " + x);
        }

        static void Main(string[] args)
        {
            Program p = new Program();
            p.processinThreads();
            Console.ReadKey();
        }

        public void DoSomething(int x, callbackDelegate callback)
        {
            Thread.Sleep(1000);
            //Console.WriteLine("I just woke up now " + x);
            callback(x);
        }

        public void processinThreads()
        {
            for (int i = 0; i < 20; i++)
            {
                Thread t = 
new Thread(new ThreadStart(()=>DoSomething(i, processCallback)));
                t.Start();
            }
        }
    }
}

【问题讨论】:

  • C# Captured Variable In Loop 的可能重复项
  • 对,我在搜索这个问题时找不到这个。好吧,我不知道这个“关闭 lambda 问题”:)
  • 避免手动创建线程。 Here 详细解释了基准原因

标签: c# multithreading lambda


【解决方案1】:
public void processinThreads()
{
    for (int i = 0; i < 20; i++)
    {
        int local = i;
        Thread t = new Thread(new ThreadStart(()=>DoSomething(local, processCallback)));
        t.Start();
    }
}

您的问题与关闭 lambda 有关。

【讨论】:

【解决方案2】:

您应该只使用 TPL,它更容易并且推荐使用手动线程管理

Parallel.For(0, 20, x => {
    Thread.Sleep(1000);
    Console.WriteLine("IN callback: The value I got is " + x);
});

这也会阻塞直到循环结束,如果你不希望你可以使用 TPL Task,但我绝对建议避免使用线程。

【讨论】:

  • 此外,这可能更有效:生成另一个线程非常昂贵。 TPL 使用(自动计算的)最佳线程数并重用它们。
  • @user676571 我打算使用应用了异步模式的 TPL。
【解决方案3】:

正如 Jakub 已经告诉你的,你需要将 i 复制到另一个局部变量 local 中。在您的代码中,代表可以直接访问i 本身,而不是i 的副本,因此他们打印出i 的当前值,这可能比您启动线程时更大。这称为闭包。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-29
    • 2017-10-02
    • 2011-01-26
    • 1970-01-01
    相关资源
    最近更新 更多