多线程冻结了统一编辑器

时间:2016-08-26 12:51:31

标签: c# multithreading unity3d mono

我将地形生成外包给线程。线程不使用任何统一api东西,线程和主线程可以访问的所有变量都通过锁进行线程安全。

我的问题是,几秒钟后(有些时间是3-4秒,有时是30秒或40秒),统一编辑器会冻结。如果我打开任务管理器,cpu和内存百分比仍在变化(cpu约为40-50%,内存约为300mb)。

我已经尝试过使用C#ThreadPool的无管线程和托管线程。与主线程的通信遍历状态变量(被锁定),因此如果任务已完成,主线程将收集数据并创建一个网格(主线程每次更新都会检查线程的状态)。

我在使用Unity 5.3 / 5.4的Windows 10和使用统一5.3 / 5.4的mac os x上尝试过它。

这是缩短的代码:

public enum SurfaceCalculationStatus{
    NewJob,
    Processing,
    DataReady,
    Ready,
    Aborted
}

public class SurfaceCalculation {
 private SurfaceCalculationStatus scs;

 private object locker = new object();

 public SurfaceCalculation(){
     Debug.Log ("Start Thread");
     //Some inits
     scs = SurfaceCalculationStatus.Ready;

     ThreadPool.QueueUserWorkItem((o) => { ThreadFunction();});
 }

 public void Init(int x, int z, int size, int gridSize, SurfaceRenderType srt, Chunk c){
     //Some inits
     lock (locker)
     {
         scs = SurfaceCalculationStatus.NewJob;
     }
 }

 private void ThreadFunction()
 {
     while (true) { 
         if(scs == SurfaceCalculationStatus.Aborted)
         {
             return;
         }
         if (scs == SurfaceCalculationStatus.NewJob) {
             lock (locker)
             {
                 scs = SurfaceCalculationStatus.Processing;

                 //Heavy calculations

                 scs = SurfaceCalculationStatus.DataReady;
             }
         }

         Thread.Sleep (10);
     }
 }

 public void AbortThread(){
     lock (locker)
     {
         scs = SurfaceCalculationStatus.Aborted;
     }
 }
 //Is called by the main thread after all data for the meshes are read
 public void SetReady(){
     lock (locker)
     {
         scs = SurfaceCalculationStatus.Ready;
     }
 }

 //Data from last calculation has been read so thread is ready for next calculation
 public bool IsReady(){
     bool buffer;
     lock (locker)
     {
         buffer = scs == SurfaceCalculationStatus.Ready;
     }
     return buffer;
 }

 //Is data ready to read and create mesh in main thread?
 public bool IsData(){
     bool buffer;
     lock (locker)
     {
         buffer = scs == SurfaceCalculationStatus.DataReady;
     }
     return buffer;
 }

}

0 个答案:

没有答案