// ---------------------------------------------------------------- #region // Private Methods /// <summary> /// オペレーションの追加 /// </summary> /// <param name="addOperation">追加するオペレーション</param> static void AddOperation(IProcessOperation addOperation) { if (_processOperationsQueue == null) { _processOperationsQueue = new Queue <IProcessOperation>(); _runningProcessOperations = new List <IProcessOperation>(); EditorApplication.update = () => { if (_runningProcessOperations.Count < EditorAsyncProcess.ProcessLimit && _processOperationsQueue.Count > 0) { _runningProcessOperations.Add(_processOperationsQueue.Dequeue()); } for (int i = 0; i < _runningProcessOperations.Count; ++i) { var operation = _runningProcessOperations[i]; if (!operation.Update()) { _runningProcessOperations.RemoveAt(i); } } }; } _processOperationsQueue.Enqueue(addOperation); }
/// <summary> /// <see cref="IProcessOperation"/> オブジェクトを登録する。 /// </summary> /// <param name="processOperation"> /// <see cref="IProcessOperation"/> オブジェクト。 /// </param> /// <returns>登録できたならば true 。既に登録済みならば false 。</returns> public bool Add(IProcessOperation processOperation) { ArgumentValidation.IsNotNull(processOperation, nameof(processOperation)); lock (this.OperationTaskLock) { if (this.Operations.Contains(processOperation)) { return(false); } // 追加 this.Operations.Add(processOperation); // タスク数が少ないなら追加 while ( this.Tasks.Count < this.TaskCountLimit && this.Tasks.Count < this.Operations.Count) { if (!this.PushTask()) { break; } } } return(true); }
/// <summary> /// <see cref="IProcessOperation.Update"/> /// メソッド呼び出しで送出された直近の例外を取得する。 /// </summary> /// <param name="processOperation"> /// <see cref="IProcessOperation"/> オブジェクト。 /// </param> /// <returns>例外。登録されていないか例外が送出されていないならば null 。</returns> public Exception GetLastException(IProcessOperation processOperation) { ArgumentValidation.IsNotNull(processOperation, nameof(processOperation)); lock (((ICollection)this.LastExceptionMap).SyncRoot) { return (this.LastExceptionMap.TryGetValue(processOperation, out var ex) ? ex : null); } }
/// <summary> /// <see cref="IProcessOperation"/> オブジェクトの登録を破棄する。 /// </summary> /// <param name="processOperation"> /// <see cref="IProcessOperation"/> オブジェクト。 /// </param> /// <returns>破棄できたならば true 。登録されていないならば false 。</returns> public bool Remove(IProcessOperation processOperation) { ArgumentValidation.IsNotNull(processOperation, nameof(processOperation)); List <Task> removedTasks = null; lock (this.OperationTaskLock) { // 位置検索 var index = this.Operations.IndexOf(processOperation); if (index < 0) { return(false); } // 削除 this.Operations.RemoveAt(index); // 次回処理対象インデックスより手前を削除したなら補正 if (this.OperationIndex > index) { --this.OperationIndex; } // タスク数が多すぎるなら終わらせる if (this.Tasks.Count > this.Operations.Count) { removedTasks = new List <Task>(); while (this.Tasks.Count > this.Operations.Count) { var task = this.PopTask(); if (task == null) { break; } removedTasks.Add(task); } } } lock (((ICollection)this.LastExceptionMap).SyncRoot) { this.LastExceptionMap.Remove(processOperation); } // lock 内で Wait するとデッドロックするので注意 if (removedTasks != null && removedTasks.Count > 0) { Task.WaitAll(removedTasks.ToArray()); } return(true); }