首页 > 解决方案 > 线程“缓慢”执行

问题描述

我从线程开始,为了学习以下简单程序而编写,稍后将使用该程序计算大约 100,000 次公式(这是一个相对简单的公式,但需要迭代的值范围)。

它的问题是我希望每个线程几乎都可以立即执行,因此整个程序几乎可以立即完成,但事实是一切都运行得太慢(大约 10 秒)......

    static readonly double TotalIterations = 1000;

    public static Iterations ActualIterations = new Iterations();

    public static void Main()
    {

        var par1 = "foo";
        var par2 = "boo";
        var par3 = 3;

        for (int i = 0; i < TotalIterations; i++)
        {
            new Thread(() => new Calculations().Calculate(par1, par2, par3)).Start();
        }

        AwaitingThreads();
    }

    static void AwaitThreads()
    {
        Console.WriteLine("Awaiting threads to finished...");

        while (true)
        {
            lock (ActualIterations)
            {
                if (ActualIterations.Progress() == TotalIterations) break;
            }
            Thread.Sleep(1 * 1000);
        }

        Console.WriteLine("All threads finished!");
    }

    public class Calculations {

        public bool Calculate(string par1, string par2, int par3)
        {
            // ...

            bool result = false;

            lock (ActualIterations)
            {
                ActualIterations.Incr();
            }

            return result;
        }
    }

    public class Iterations
    {
        int progress = 0;

        public void Incr()
        {
            progress++;
        }

        public int Progress()
        {
            return progress;
        }
    }

我也尝试过使用这样的线程池,但没有任何改进......

    static readonly double TotalIterations = 1000;

    static string par1 = "foo";
    static string par2 = "boo";
    static int par3 = 3;

    public static Iterations ActualIterations = new Iterations();

    public static void Main()
    {
        ThreadPool.QueueUserWorkItem(MyThreadPool);

        AwaitThreads();
    }

    static void AwaitThreads()
    {
        Console.WriteLine("Awaiting threads to finished...");

        while (true)
        {
            lock (ActualIterations)
            {
                if (ActualIterations.Progress() == TotalIterations) break;
            }
            Thread.Sleep(1 * 1000);
        }

        Console.WriteLine("All threads finished!");
    }

    static void MyThreadPool(Object stateInfo)
    {
        for (int i = 0; i < TotalIterations; i++)
        {
            new Thread(() => new Calculations().Calculate(par1, par2, par3)).Start();
        }
    }

    public class Calculations {

        public bool Calculate(string par1, string par2, int par3)
        {
            // ...

            bool result = false;

            lock (ActualIterations)
            {
                ActualIterations.Incr();
            }

            return result;
        }
    }

    public class Iterations
    {
        int progress = 0;

        public void Incr()
        {
            progress++;
        }

        public int Progress()
        {
            return progress;
        }
    }

当我在此示例中退出使用线程并使用静态方法时,在我的for循环中按顺序执行它,程序在 1 秒内完成......

任何人都可以告诉我我在这些线程中做错了什么吗?

标签: c#multithreading

解决方案


问题是我希望每个线程几乎都能立即执行

对。您忽略了创建新线程是一项相对昂贵的操作这一事实。比“获取锁并递增整数”要昂贵得多,这是您线程中所做的工作。

给一个真实的世界比较,这有点像订购一辆新车,等待它交付,然后驾驶它 1 公里。这比步行1公里要慢。

使用线程池会更快,但您没有正确使用它 - 您正在启动一个线程池任务,然后再次创建所有其他线程。

我会鼓励你看看 using Task<T>,它通常使用引擎盖下的线程池,并且通常是这种工作的更现代的抽象。


推荐阅读