多线程+缓存计算

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

namespace TaskTool
{
    using System.Collections;
    using System.Collections.Concurrent;
    using System.Diagnostics;
    using System.Threading;

    class Program
    {
        private int TotalNum;
        private const int MAXDICNUM = 40000000;

        private static void Main(string[] args)
        {
            var stopWath = new Stopwatch();

            var allCells=new List<Point>();
            var cash = new ConcurrentDictionary<DisCashPair, short>();
          
            InitialCells(allCells);

            stopWath.Start();
            Cal(allCells, cash, 0, allCells.Count);
            stopWath.Stop();
            Console.WriteLine(string.Format("Single CPU {0},Cash num{1}", stopWath.ElapsedMilliseconds, cash.Count));

            cash.Clear();
            stopWath.Reset();
            stopWath.Start();

            var cts = new CancellationTokenSource();
            var tf = new TaskFactory(cts.Token, TaskCreationOptions.AttachedToParent,
                                       TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);

            var blockNum = (int)Math.Ceiling(allCells.Count*1.0/CPUTool.GetCpuNum());

            var calTasks = new Task[CPUTool.GetCpuNum()];

            for (int i = 0; i < CPUTool.GetCpuNum(); i++)
            {
                var startNum = i * blockNum;
                var endNum = (i + 1) * blockNum;
                if (endNum >= allCells.Count)
                {
                    endNum = allCells.Count - 1;
                }

                calTasks[i] =
                    Task.Factory.StartNew(() => Cal(allCells,cash, startNum, endNum));
            }

            var endTask = tf.ContinueWhenAll(calTasks, (tasks) =>{});
            endTask.Wait(cts.Token);
            //Task.WaitAll(calTasks.ToArray());

            stopWath.Stop();
            Console.WriteLine(string.Format("Single CPU {0},Cash num{1}", stopWath.ElapsedMilliseconds, cash.Count));
            //Console.WriteLine(string.Format("Single CPU {0},Cash num{1}", stopWath.ElapsedMilliseconds, cash.Count));




        }

        //private static Dictionary<DisCashPair, short> Finish(Task<Dictionary<DisCashPair, short>>[] tasks)
        //{
        //    IEnumerable<KeyValuePair<DisCashPair, short>> result = new Dictionary<DisCashPair, short>();

        //    result = tasks.Select(t => t.Result).Aggregate(result, (current, dic) => current.Union(dic));

        //    return result.ToDictionary(r => r.Key, r => r.Value);
        //}


        private static ConcurrentDictionary<DisCashPair, short> Cal(List<Point> allCells, int start, int end)
        {
            var cash = new ConcurrentDictionary<DisCashPair, short>();
            for (int i = start; i < end; i++)
            {
                var cell = allCells[i];
                CalDis(cell, allCells, cash);
            }
            return cash;
        }

        private static void Cal(List<Point> allCells, ConcurrentDictionary<DisCashPair, short> cash, int start, int end)
        {
            for (int i = start; i < end; i++)
            {
                var cell = allCells[i];
                CalDis(cell, allCells, cash);
            }
        }

        private static void CalDis(Point cell, List<Point> allCells, ConcurrentDictionary<DisCashPair, short> cash)
        {
            foreach (var desCell in allCells)
            {
                short dis;
                if (cash.TryGetValue(new DisCashPair(cell, desCell), out dis))
                {
                    continue;
                }
                else
                {
                    cash[new DisCashPair(cell, desCell)] = GetDis(cell,desCell);
                }
            }
        }

        private static short GetDis(Point cell, Point desCell)
        {
            var difX = (cell.X - desCell.X);
            var difY = (cell.Y - desCell.Y);
            var dis = Math.Sqrt(difX*difX + difY*difY);

            return (short) (Math.Round(dis, 2)*100);
        }

        private static void InitialCells(List<Point> allCells)
        {
            var rd = new Random();

            for (int i = 0; i < 5000; i++)
            {
                allCells.Add(new Point()
                {
                    ID=i,
                    X = rd.NextDouble(),
                    Y = rd.NextDouble()
                });
            }
        }
    }

    public class DisCashPair
    {
        public Point Src;
        public Point Des;

        public DisCashPair(Point src,Point des)
        {
            Src = src;
            Des = des;
        }

        public override int GetHashCode()
        {
            return (Src.ID*397) ^ (Des.ID*397);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, null)) return false;
            if (obj.GetType() != typeof (DisCashPair)) return false;
            return Equals((DisCashPair) obj);
        }

        private bool Equals(DisCashPair pair)
        {
            return (pair.Src.ID == this.Src.ID && pair.Des.ID == this.Des.ID) ||
                   (pair.Src.ID == this.Des.ID && pair.Des.ID == this.Src.ID);
        }
    }

    public struct Point
    {
        public int ID;
        public double X;
        public double Y;
    }

    public static class CPUTool
    {
        private static int CPUNUM=Int32.MaxValue;

        private const string SEARCHSR = "Select * from Win32_Processor";
        private const string CORESNUM = "NumberOfCores";

        public static int GetCpuNum()
        {
            if (CPUNUM == Int32.MaxValue)
            {
                CPUNUM =
                    new System.Management.ManagementObjectSearcher(SEARCHSR).Get()
                        .Cast<ManagementBaseObject>()
                        .Sum(item => int.Parse(item[CORESNUM].ToString()));
            }

            return CPUNUM;
        }

    }
}

  

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Management;using System.Threading.Tasks;
namespace TaskTool{    using System.Collections;    using System.Collections.Concurrent;    using System.Diagnostics;    using System.Threading;
    class Program    {        private int TotalNum;        private const int MAXDICNUM = 40000000;
        private static void Main(string[] args)        {            var stopWath = new Stopwatch();
            var allCells=new List<Point>();            var cash = new ConcurrentDictionary<DisCashPair, short>();                      InitialCells(allCells);
            stopWath.Start();            Cal(allCells, cash, 0, allCells.Count);            stopWath.Stop();            Console.WriteLine(string.Format("Single CPU {0},Cash num{1}", stopWath.ElapsedMilliseconds, cash.Count));
            cash.Clear();            stopWath.Reset();            stopWath.Start();
            var cts = new CancellationTokenSource();            var tf = new TaskFactory(cts.Token, TaskCreationOptions.AttachedToParent,                                       TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
            var blockNum = (int)Math.Ceiling(allCells.Count*1.0/CPUTool.GetCpuNum());
            var calTasks = new Task[CPUTool.GetCpuNum()];
            for (int i = 0; i < CPUTool.GetCpuNum(); i++)            {                var startNum = i * blockNum;                var endNum = (i + 1) * blockNum;                if (endNum >= allCells.Count)                {                    endNum = allCells.Count - 1;                }
                calTasks[i] =                    Task.Factory.StartNew(() => Cal(allCells,cash, startNum, endNum));            }
            var endTask = tf.ContinueWhenAll(calTasks, (tasks) =>{});            endTask.Wait(cts.Token);            //Task.WaitAll(calTasks.ToArray());
            stopWath.Stop();            Console.WriteLine(string.Format("Single CPU {0},Cash num{1}", stopWath.ElapsedMilliseconds, cash.Count));            //Console.WriteLine(string.Format("Single CPU {0},Cash num{1}", stopWath.ElapsedMilliseconds, cash.Count));



        }
        //private static Dictionary<DisCashPair, short> Finish(Task<Dictionary<DisCashPair, short>>[] tasks)        //{        //    IEnumerable<KeyValuePair<DisCashPair, short>> result = new Dictionary<DisCashPair, short>();
        //    result = tasks.Select(t => t.Result).Aggregate(result, (current, dic) => current.Union(dic));
        //    return result.ToDictionary(r => r.Key, r => r.Value);        //}

        private static ConcurrentDictionary<DisCashPair, short> Cal(List<Point> allCells, int start, int end)        {            var cash = new ConcurrentDictionary<DisCashPair, short>();            for (int i = start; i < end; i++)            {                var cell = allCells[i];                CalDis(cell, allCells, cash);            }            return cash;        }
        private static void Cal(List<Point> allCells, ConcurrentDictionary<DisCashPair, short> cash, int start, int end)        {            for (int i = start; i < end; i++)            {                var cell = allCells[i];                CalDis(cell, allCells, cash);            }        }
        private static void CalDis(Point cell, List<Point> allCells, ConcurrentDictionary<DisCashPair, short> cash)        {            foreach (var desCell in allCells)            {                short dis;                if (cash.TryGetValue(new DisCashPair(cell, desCell), out dis))                {                    continue;                }                else                {                    cash[new DisCashPair(cell, desCell)] = GetDis(cell,desCell);                }            }        }
        private static short GetDis(Point cell, Point desCell)        {            var difX = (cell.X - desCell.X);            var difY = (cell.Y - desCell.Y);            var dis = Math.Sqrt(difX*difX + difY*difY);
            return (short) (Math.Round(dis, 2)*100);        }
        private static void InitialCells(List<Point> allCells)        {            var rd = new Random();
            for (int i = 0; i < 5000; i++)            {                allCells.Add(new Point()                {                    ID=i,                    X = rd.NextDouble(),                    Y = rd.NextDouble()                });            }        }    }
    public class DisCashPair    {        public Point Src;        public Point Des;
        public DisCashPair(Point src,Point des)        {            Src = src;            Des = des;        }
        public override int GetHashCode()        {            return (Src.ID*397) ^ (Des.ID*397);        }
        public override bool Equals(object obj)        {            if (ReferenceEquals(obj, null)) return false;            if (obj.GetType() != typeof (DisCashPair)) return false;            return Equals((DisCashPair) obj);        }
        private bool Equals(DisCashPair pair)        {            return (pair.Src.ID == this.Src.ID && pair.Des.ID == this.Des.ID) ||                   (pair.Src.ID == this.Des.ID && pair.Des.ID == this.Src.ID);        }    }
    public struct Point    {        public int ID;        public double X;        public double Y;    }
    public static class CPUTool    {        private static int CPUNUM=Int32.MaxValue;
        private const string SEARCHSR = "Select * from Win32_Processor";        private const string CORESNUM = "NumberOfCores";
        public static int GetCpuNum()        {            if (CPUNUM == Int32.MaxValue)            {                CPUNUM =                    new System.Management.ManagementObjectSearcher(SEARCHSR).Get()                        .Cast<ManagementBaseObject>()                        .Sum(item => int.Parse(item[CORESNUM].ToString()));            }
            return CPUNUM;        }
    }}

原文地址:https://www.cnblogs.com/suriyel/p/3738074.html