获得意外的多线程行为

时间:2014-01-30 09:54:41

标签: c# multithreading

我正在尝试使用线程来获取素数列表。但是当我运行程序时,我在结果中得到了多余的素数。

static void Main(string[] args)
        {
            try
            {
                var r2 = DoThread();
                Array.Sort(r2);
            }
            catch (Exception e)
            { }
        }

public static int[] DoThread()
        {
            var task = new List<MyThread>(){
                new MyThread(){start = 3, end = 25000},
                new MyThread(){start = 25001, end = 50000},
                new MyThread(){start = 50001, end = 75000},
                new MyThread(){start = 75001, end = 100000-3}
            };
            var threads = new List<Thread>()
            {
                new Thread(task[0].MyDelegate),
                new Thread(task[1].MyDelegate),
                new Thread(task[2].MyDelegate),
                new Thread(task[3].MyDelegate)
            };

            threads.ForEach(t => { t.Start(); });
            threads.ForEach(t => { t.Join(); });

            var res = new List<int>();
            task.ForEach(t => res.AddRange(t.result));
            return res.ToArray();
        }

public class MyThread
    {
        public int[] result;
        public int start;
        public int end;

        public void MyDelegate()
        {
            IEnumerable<int> numbers = Enumerable.Range(start, end);
            var parallelQuery =
              from n in numbers
              where Enumerable.Range(2, (int)Math.Sqrt(n)).All(i => n % i > 0)
              select n;
            result = parallelQuery.ToArray();
        }
    }

1 个答案:

答案 0 :(得分:1)

Enumerable.Range(start, end)不会使用起始端对。它需要startcount

您可以通过使用调试器并检查运行时状态来自己发现此错误。只是查看有缺陷的代码通常不会导致找到它。需要调查。

除了你的代码是线程安全的,虽然远比使用像PLINQ这样的东西复杂得多:

var res = tasks.AsParallel().SelectMany(t => t.GetPrimes()).ToList();

在更高层次上工作。不要管理线程。