C#计数线程不工作

时间:2016-01-31 19:54:48

标签: c# multithreading

大家下午好。 我是Parallel.ForEach的新手,甚至更新的线程,我想问你对这段代码有什么问题的看法。

    using System;
    using System.Collections.Generic;

    using System.Linq;
    using System.Text;
    using System.Threading;

namespace MultiThreading_Example
{

    class theMeter {

        int count1 = 0;

        public void CounterMeter()
        {
            while (this.count1 < 10000)
            {
                this.count1++;
                Console.WriteLine(this.count1);
            }
        }

    }


    class Program
    {
        static void Main(string[] args)
        {

            theMeter met = new theMeter();

            ThreadStart countForMe = new ThreadStart(met.CounterMeter);

            for (int i = 0; i < 1000; i++)
            {
                Thread t1 = new Thread(countForMe);
                t1.Start();
                t1.Join();
                t1.Abort();
            }

            Console.ReadLine();

        }
    }
}

知道这有什么问题吗?我的意思是,我尝试过没有t1.Join()并尝试在一个线程上进行。一切都在同一速度。我怎样才能让程序更快地处理?

提前致谢!

1 个答案:

答案 0 :(得分:0)

以下是工作示例示例。区别在于每个线程都存储在列表中并且并行启动,然后最后我们等待每个线程。

class theMeter
{
    private int count1 = 0;

    public void CounterMeter()
    {
        while (this.count1 < 10000)
        {
            this.count1++;
            Console.WriteLine(this.count1);
        }
    }
}
class Program
{
    static void Main(string[] args)
    {
        theMeter met = new theMeter();
        ThreadStart countForMe = new ThreadStart(met.CounterMeter);

        List<Thread> threads = new List<Thread>();
        for (int i = 0; i < 10; i++)
        {
            Thread t1 = new Thread(countForMe);
            t1.Start();
            threads.Add(t1);
        }

        // here we will wait for completion of every thread that was created and added to list
        threads.ForEach(t => t.Join());
        Console.ReadLine();
    }
}

此代码有几个值得一提的问题:

  1. 每个线程都使用相同的theMeter实例,因此每个线程都将迭代相同的this.count1变量,因此 它不是那么线程安全 即可。 IMO,更好的方法是为每个线程创建自己的实例,并为每个线程划分工作。因此,他们不会分享相同的资源,也不会导致共享资源访问问题。
  2. 如果任何线程卡住,那么您的程序将会冻结。由于Join将等待无限的时间。如果您的线程可能需要花费大量时间(网络,数据库等),那么您可以使用Join超时,然后调用Abort。但是仍然不建议使用Abort方法,因为线程应该以优雅的方式完成他的逻辑,而不是Abort方法的残酷中断。
  3. 在您的原始示例中,您有1000个线程,并且它太多了,因为它们会争夺CPU资源并且可能会使速度变得更慢。但这将取决于他们将要做的实际事情以及瓶颈所在。如果这是CPU密集型任务,则线程计数应与CPU计数类似。如果他们正在做网络请求,那么它可能取决于网络带宽。
  4. 另一种方法可能是使用真正的Parallel.ForEachTask类,这可以使事情变得更容易一些。
  5. 实际Parallel.ForEach的示例如下:

    class Program
    {
        static void Main(string[] args)
        {
            theMeter met = new theMeter();
    
            Enumerable.Range(0, 1000).AsParallel().ForAll((i) => met.CounterMeter());
            Console.ReadLine();
    
        }
    }
    

    但是你在这里没有那么多的灵活性,但它更容易