c#多线程仅使用25%的CPU

c#多线程仅使用25%的CPU,c#,parallel-processing,C#,Parallel Processing,我有一个遗传嵌套算法的过程,我正在尝试多线程。该过程如下所示 using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace ConsoleApp1 { class Program { static void Main(string[] args)

我有一个遗传嵌套算法的过程,我正在尝试多线程。该过程如下所示

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
  class Program
  {
    static void Main(string[] args)
    {
      CurrentNest = new CuttingRun();
      for (int i = 0; i < 80; i++)
      {
        double w = GetRandomNumber(24, 50);
        double h = GetRandomNumber(10, 15);
        CurrentNest.PartList.Add(new LwCube { Width = w, Height = h, PartID = i });
      }
      //Task.Run(() =>
      //{
      //  Parallel.For(0, 64, (i) => Parallel_Nest());
      //});
      while (true)
      {
        Parallel_Nest();
      }
      //Console.ReadKey();
    }

    public static double GetRandomNumber(double minimum, double maximum)
    {
      Random random = new Random();
      return random.NextDouble() * (maximum - minimum) + minimum;
    }

    public static CuttingRun CurrentNest { get; set; }
    public static void Parallel_Nest()
    {
      Random random = new Random();
      int randomNumber = random.Next(2000, 10000);     
      var retVal = Nester.Nest_Parts(CurrentNest, randomNumber);
      CurrentNest.Iterations++;
      if (CurrentNest.SavedList.Count > 0)
      {
        if (retVal.Count < CurrentNest.SavedList.Count)
        {
          CurrentNest.SavedList = retVal;          
        }
      }
      else
      {
        CurrentNest.SavedList = retVal;
      }
      Console.WriteLine(CurrentNest.Iterations.ToString() + " " + CurrentNest.SavedList.Count.ToString());
      if (CurrentNest.SavedList != retVal)
      {
        retVal.Clear();
      }
    }    
  }


//Models
public class LwSheet
  {
    public LwSheet(double width, double height)
    {
      SheetWidth = width;
      SheetHeight = height;
      FreeRectangles.Add(new LwCube { Width = width, Height = height, X = 0, Y = 0 });
    }
    public List<LwCube> UsedRectangles = new List<LwCube>();
    public List<LwCube> FreeRectangles = new List<LwCube>();
    public double SheetWidth { get; set; }
    public double SheetHeight { get; set; }
    public double TotalUsed { get; set; }
    public bool Place_Part(LwCube prt)
    {
      bool retVal = false;
      LwCube bestNode = FindPositionForBestAreaFit(prt);
      //if the bestNode has a height then add our parts to the list
      if (bestNode.Height > 0)
      {
        bestNode.PartID = prt.PartID;
        int numRectanglesToProcess = FreeRectangles.Count;
        for (int i = 0; i < numRectanglesToProcess; ++i)
        {
          if (SplitFreeNode(FreeRectangles[i], ref bestNode))
          {
            FreeRectangles.RemoveAt(i);
            --i;
            --numRectanglesToProcess;
          }
        }

        PruneFreeList();
        UsedRectangles.Add(bestNode);
        retVal = true;
      }
      return retVal;
    }
    bool SplitFreeNode(LwCube freeNode, ref LwCube usedNode)
    {
      // Test with SAT if the rectangles even intersect.
      if (usedNode.X >= freeNode.X + freeNode.Width || usedNode.X + usedNode.Width <= freeNode.X ||
        usedNode.Y >= freeNode.Y + freeNode.Height || usedNode.Y + usedNode.Height <= freeNode.Y)
        return false;

      if (usedNode.X < freeNode.X + freeNode.Width && usedNode.X + usedNode.Width > freeNode.X)
      {
        // New node at the top side of the used node.
        if (usedNode.Y > freeNode.Y && usedNode.Y < freeNode.Y + freeNode.Height)
        {
          LwCube newNode = new LwCube { Width = freeNode.Width, X = freeNode.X, Y = freeNode.Y };
          newNode.Height = usedNode.Y - newNode.Y;
          FreeRectangles.Add(newNode);
        }

        // New node at the bottom side of the used node.
        if (usedNode.Y + usedNode.Height < freeNode.Y + freeNode.Height)
        {
          LwCube newNode = new LwCube { Width = freeNode.Width, X = freeNode.X };
          newNode.Y = usedNode.Y + usedNode.Height;
          newNode.Height = freeNode.Y + freeNode.Height - (usedNode.Y + usedNode.Height);
          FreeRectangles.Add(newNode);
        }
      }

      if (usedNode.Y < freeNode.Y + freeNode.Height && usedNode.Y + usedNode.Height > freeNode.Y)
      {
        // New node at the left side of the used node.
        if (usedNode.X > freeNode.X && usedNode.X < freeNode.X + freeNode.Width)
        {
          LwCube newNode = new LwCube { Height = freeNode.Height, X = freeNode.X, Y = freeNode.Y };
          newNode.Width = usedNode.X - newNode.X;
          FreeRectangles.Add(newNode);
        }

        // New node at the right side of the used node.
        if (usedNode.X + usedNode.Width < freeNode.X + freeNode.Width)
        {
          LwCube newNode = new LwCube { Height = freeNode.Height, Y = freeNode.Y };
          newNode.X = usedNode.X + usedNode.Width;
          newNode.Width = freeNode.X + freeNode.Width - (usedNode.X + usedNode.Width);
          FreeRectangles.Add(newNode);
        }
      }

      return true;
    }    
    void PruneFreeList()
    {
      for (int i = 0; i < FreeRectangles.Count; ++i)
        for (int j = i + 1; j < FreeRectangles.Count; ++j)
        {
          if (IsContainedIn(FreeRectangles[i], FreeRectangles[j]))
          {
            FreeRectangles.RemoveAt(i);
            --i;
            break;
          }
          if (IsContainedIn(FreeRectangles[j], FreeRectangles[i]))
          {
            FreeRectangles.RemoveAt(j);
            --j;
          }
        }
    }
    bool IsContainedIn(LwCube a, LwCube b)
    {
      return a.X >= b.X && a.Y >= b.Y
        && a.X + a.Width <= b.X + b.Width
        && a.Y + a.Height <= b.Y + b.Height;
    }
    LwCube FindPositionForBestAreaFit(LwCube prt)
    {
      LwCube bestNode = new LwCube();
      var bestAreaFit = SheetWidth * SheetHeight;
      for (int i = 0; i < FreeRectangles.Count; ++i)
      {
        double areaFit = FreeRectangles[i].Width * FreeRectangles[i].Height - prt.Width * prt.Height;

        // Try to place the rectangle in upright (non-flipped) orientation.
        if (FreeRectangles[i].Width >= prt.Width && FreeRectangles[i].Height >= prt.Height)
        {
          if (areaFit < bestAreaFit)
          {
            bestNode.X = FreeRectangles[i].X;
            bestNode.Y = FreeRectangles[i].Y;
            bestNode.Height = prt.Height;
            bestNode.Width = prt.Width;
            bestAreaFit = areaFit;
          }
        }
      }
      return bestNode;
    }   
  }

  public class LwCube
  {
    public int PartID { get; set; }
    public double Width { get; set; }
    public double Height { get; set; }
    public double X { get; set; }
    public double Y { get; set; }
  }

  public class CuttingRun
  {    
    public List<LwCube> PartList = new List<LwCube>();
    public List<LwSheet> SavedList = new List<LwSheet>();
    public List<LwSheet> Sheets = new List<LwSheet>();
    public int Iterations { get; set; }
  }


//Actions
public static class Nester
  {
    public static List<LwSheet> Nest_Parts(CuttingRun cuttingRun, int loopCount)
    {
      var SheetList = new List<LwSheet>();
      List<LwCube> partList = new List<LwCube>();
      partList.AddRange(cuttingRun.PartList);
      while (partList.Count > 0)
      {
        LwSheet newScore = new LwSheet(97, 49);
        List<LwCube> addingParts = new List<LwCube>();
        foreach (var prt in partList)
        {
          addingParts.Add(new LwCube { Width = prt.Width, Height = prt.Height, PartID = prt.PartID });
        }
        if (addingParts.Count > 0)
        {
          var sheets = new ConcurrentBag<LwSheet>();
          Parallel.For(0, loopCount, (i) =>
          {
            var hmr = new LwSheet(97, 49);
            Add_Parts_To_Sheet(hmr, addingParts);
            sheets.Add(hmr);
          });
          //for (int i = 0; i < loopCount; i++)
          //{
          //  var hmr = new LwSheet(97, 49);

          //  Add_Parts_To_Sheet(hmr, addingParts, addToLarge, addToMedium);
          //  sheets.Add(hmr);
          //}
          addingParts.Clear();
          var bestSheet = sheets.Where(p => p != null).OrderByDescending(p => p.TotalUsed).First();
          sheets = null;
          newScore = bestSheet;
          foreach (var ur in newScore.UsedRectangles)
          {
            partList.Remove(partList.Single(p => p.PartID == ur.PartID));
          }
          SheetList.Add(newScore);
        }
      }
      return SheetList;
    }       
    public static void Add_Parts_To_Sheet(LwSheet sh, List<LwCube> parts)
    {
      var myList = new List<LwCube>();
      myList.AddRange(parts);
      myList.Shuffle();
      foreach (var prt in myList)
      {
        sh.Place_Part(prt);
      }
      myList.Clear();
      foreach (var ur in sh.UsedRectangles)
      {
        sh.TotalUsed += ur.Width * ur.Height;
      }
    }

    [ThreadStatic] private static Random Local;
    public static Random ThisThreadsRandom
    {
      get { return Local ?? (Local = new Random(unchecked(Environment.TickCount * 31 + System.Threading.Thread.CurrentThread.ManagedThreadId))); }
    }

    public static void Shuffle<T>(this IList<T> list)
    {
      int n = list.Count;
      while (n > 1)
      {
        n--;
        int k = ThisThreadsRandom.Next(n + 1);
        T value = list[k];
        list[k] = list[n];
        list[n] = value;
      }
    }
  }
}
使用系统;
使用System.Collections.Concurrent;
使用System.Collections.Generic;
使用System.Linq;
使用System.Threading.Tasks;
名称空间控制台EAPP1
{
班级计划
{
静态void Main(字符串[]参数)
{
CurrentNest=新的切割运行();
对于(int i=0;i<80;i++)
{
双w=随机数(24,50);
双h=GetRandomNumber(10,15);
CurrentNest.PartList.Add(新的LwCube{Width=w,Height=h,PartID=i});
}
//Task.Run(()=>
//{
//对于(0,64,(i)=>Parallel_Nest());
//});
while(true)
{
平行_嵌套();
}
//Console.ReadKey();
}
公共静态双随机数(最小值加倍,最大值加倍)
{
随机=新随机();
返回random.NextDouble()*(最大值-最小值)+最小值;
}
公共静态剪切运行CurrentNest{get;set;}
公共静态void并行_Nest()
{
随机=新随机();
int randomNumber=random.Next(2000,10000);
var retVal=Nester.Nest\u零件(CurrentNest,randomNumber);
CurrentNest.Iterations++;
如果(CurrentNest.SavedList.Count>0)
{
if(retVal.Count0)
{
bestNode.PartID=prt.PartID;
int numRectanglesToProcess=自由矩形。计数;
对于(int i=0;i=freeNode.X+freeNode.Width | | usedNode.X+usedNode.Width=freeNode.Y+freeNode.Height | | usedNode.Y+usedNode.Height freeNode.X)
{
//新节点位于已使用节点的顶部。
if(usedNode.Y>freeNode.Y&&usedNode.YfreeNode.Y)
{
//新节点位于已使用节点的左侧。
if(usedNode.X>freeNode.X&&usedNode.X=b.X&&a.Y>=b.Y
&&a.X+a.宽度=额定高度)
{
如果(区域配合<最佳区域配合)
{
bestNode.X=自由矩形[i].X;
bestNode.Y=自由矩形[i].Y;
bestNode.Height=prt.Height;
bestNode.Width=prt.Width;
bestAreaFit=areaFit;
}
}
}
返回最佳节点;
}   
}
公共类LwCube
{
公共int PartID{get;set;}
公共双宽度{get;set;}
公共双高{get;set;