Beispiel #1
0
 public void NoBlockingEnqueue(IBlockQueue <Task> _queue, Task _task)
 {
     if (!_queue.TryEnqueue(_task))
     {
         AddWaitEnqueueTask(_queue, _task);
     }
     ;
 }
Beispiel #2
0
 public ReadBuffer(ISettings settings, IBlockQueue emptyBlocks, IBlockQueue filledBlocks, int capacity)
 {
     this.settings     = settings;
     this.EmptyBlocks  = emptyBlocks;
     this.FilledBlocks = filledBlocks;
     for (int i = 0; i < capacity; i++)
     {
         EmptyBlocks.Enqueue(new DataBlock(settings.BlockSizeBytes));
     }
 }
Beispiel #3
0
        bool TryDequeueWaitEqueueTasks(IBlockQueue <Task> _targetQueue, out Task _task)
        {
            var _count = waitEnqueueTasks.Count;

            _task = null;
            for (int i = 0; i < _count; i++)
            {
                var _info = waitEnqueueTasks[i];
                if (_info.targetQueue == _targetQueue)
                {
                    _task = _info.task;
                    waitEnqueueTasks.RemoveAt(i);
                    return(true);
                }
            }
            return(false);
        }
Beispiel #4
0
        private void DispathTasks(List <Task> _tasks, HashSet <Task> _taskSet, IBlockQueue <Task> _targetQueue)
        {
            var _count = _tasks.Count;

            for (int i = 0; i < _count; i++)
            {
                var _info = _tasks[i];
                //注意必须在当前帧执行的任务的添加一定是在主线程中,所以一定可以投递成功
                //其他的任务投递就不是必须全部投递成功,因为不需要一定在本帧完成
                if (_targetQueue.TryEnqueue(_info))
                {
                    _tasks.RemoveAt(i);
                    _taskSet.Remove(_info);
                    --i;
                    --_count;
                }
            }
        }
Beispiel #5
0
 public ThreadsCreator(IBlockDictionary outputBuffer,
                       IReader blockReader,
                       IWriter blockWriter,
                       IBlockQueue unusedSourceBlocks,
                       IBlockQueue filledSourceBlocks,
                       IStatistics stats,
                       ISettings settings,
                       IReadBuffer readBuffer)
 {
     this.outputBuffer       = outputBuffer;
     this.blockReader        = blockReader;
     this.blockWriter        = blockWriter;
     this.unusedSourceBlocks = unusedSourceBlocks;
     this.filledSourceBlocks = filledSourceBlocks;
     this.stats      = stats;
     this.settings   = settings;
     this.readBuffer = readBuffer;
 }
Beispiel #6
0
 public void DoStart(
     int _threadCount
     , int _maxTaskCount
     , FuncCreateWorker _WorkCreateFunc
     , FuncDealTask _OnDealTaskEvent
     , int _MaxRunTimePreFrameInMs = 10
     )
 {
     if (isInited)
     {
         Debug.LogError("重复初始化:逻辑错误");
         return;
     }
     isInited               = true;
     mainThread             = Thread.CurrentThread;
     threadWorkers          = new List <ThreadWorker>();
     threads                = new List <Thread>();
     OnDealTaskEvent        = _OnDealTaskEvent;
     MaxRunTimePreFrameInMs = _MaxRunTimePreFrameInMs;
     MaxTaskCount           = _maxTaskCount;
     AnyThreadTasks         = CreateBlockQueue(MaxTaskCount * 1);
     MainThreadTasks        = CreateBlockQueue(MaxTaskCount * 2);
     CurFrameTasks          = CreateBlockQueue(MaxTaskCount * 10);
     WorkCreateFunc         = _WorkCreateFunc;
     mainThreadWorker       = _WorkCreateFunc(this, -1);
     for (int _i = 0; _i < _threadCount; ++_i)
     {
         //每个线程都分配避免互相之间锁 而挂起
         var    _worker = WorkCreateFunc(this, _i);
         Thread _thread = new Thread(_worker.Run);
         _thread.IsBackground = true;
         threadWorkers.Add(_worker);
         threads.Add(_thread);
     }
     for (int _i = 0; _i < _threadCount; _i++)
     {
         threads[_i].Start();
     }
 }
Beispiel #7
0
        void DispatchWaitEnqueueTasks(IBlockQueue <Task> _targetQueue)
        {
            var _count = waitEnqueueTasks.Count;

            for (int i = 0; i < _count; i++)
            {
                var _info = waitEnqueueTasks[i];
                if (_info.targetQueue == _targetQueue)
                {
                    //注意必须在主线程执行的队列  一定可以装进去
                    if (_targetQueue.TryEnqueue(_info.task))
                    {
                        waitEnqueueTasks.RemoveAt(i);
                        --i;
                        --_count;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
Beispiel #8
0
        IBlockQueue <Task> GetQueueFromType(EThreadContext _queueType)
        {
            IBlockQueue <Task> _nextQueue = null;

            switch (_queueType)
            {
            case EThreadContext.MainThreadAndInCurFrame:
                _nextQueue = CurFrameTasks;
                break;

            case EThreadContext.MainThread:
                _nextQueue = MainThreadTasks;
                break;

            case EThreadContext.AnyThread:
                _nextQueue = AnyThreadTasks;
                break;

            default:
                break;
            }
            return(_nextQueue);
        }
Beispiel #9
0
 public void BlockingEnqueue(IBlockQueue <Task> _queue, Task _task)
 {
     _queue.Enqueue(_task);
 }
Beispiel #10
0
 public void AddWaitEnqueueTask(IBlockQueue <Task> _queue, Task _task)
 {
     waitEnqueueTasks.Add(new PendingEnqueueTasks(_queue, _task));
 }
Beispiel #11
0
 public void DealQueue(IBlockQueue <Task> _todoQueue, ThreadWorker _thread_worker, Func <bool> _FuncIsTimeOut, bool _isInMainThread = true)
 {
     while (true)
     {
         Task _task = null;
         if (!_isInMainThread)
         {
             _task = _todoQueue.Dequeue();
         }
         else
         {
             if (!_todoQueue.TryDequeue(out _task))
             {
                 if (_todoQueue == CurFrameTasks)
                 {
                     if (!TryDequeueWaitEqueueTasks(_todoQueue, out _task))
                     {
                         return;
                     }
                 }
                 else
                 {
                     if (_FuncIsTimeOut())
                     {
                         return;
                     }
                     if (!TryDequeueWaitEqueueTasks(_todoQueue, out _task))
                     {
                         return;
                     }
                 }
             }
         }
         _thread_worker.ResetThreadLoacalStorage();
         _task.threadLocalStorage = _thread_worker;
         if (!_task.IsFinished)
         {
             //处理还未完成的任务
             try {
                 DealTask(_task);
                 _task.MoveNextPhase();
                 //根据当前任务的状态派发到不同的队列中
                 var _queueType = _task.GetTargetQueueType();
                 var _nextQueue = GetQueueFromType(_queueType);
                 if (_isInMainThread)
                 {
                     //为了防止阻塞
                     if (!_nextQueue.TryEnqueue(_task))
                     {
                         AddWaitEnqueueTask(_nextQueue, _task);
                     }
                 }
                 else
                 {
                     _nextQueue.Enqueue(_task);
                 }
             } catch (System.Threading.ThreadInterruptedException) {
                 //正常现象
                 _task.IsInterrupted = true;
                 if (_isInMainThread)
                 {
                     NoBlockingEnqueue(_task);
                 }
                 else
                 {
                     BlockingEnqueue(MainThreadTasks, _task);
                 }
             } catch (System.Exception _e) {
                 _task.Exception = _e;
                 if (_isInMainThread)
                 {
                     NoBlockingEnqueue(_task);
                 }
                 else
                 {
                     BlockingEnqueue(MainThreadTasks, _task);
                 }
             }
             if (_FuncIsTimeOut != null && _FuncIsTimeOut())
             {
                 break;
             }
         }
         else
         {
             Debug.Assert(_isInMainThread, "LogicError: Callback Must in mainThread");
             //处理已经完成了的任务,进行回调
             try {
                 if (_task.IsInterrupted)
                 {
                     _task.OnInterrupted();
                 }
                 else
                 {
                     _task.OnFinished();
                 }
                 if (_FuncIsTimeOut != null && _FuncIsTimeOut())
                 {
                     break;
                 }
             } catch (Exception _e) {
                 //这里已经是处理完成的任务相关
                 Debug.LogError("处理任务完成回调抛出异常: " + _e + " _task " + _task.ToString());
             }
         }
     }
 }
Beispiel #12
0
 public PendingEnqueueTasks(IBlockQueue <Task> _targetQueue, Task _task)
 {
     targetQueue = _targetQueue;
     task        = _task;
 }