From 36a845a0fba0780b4f786ce15c43369c816b0697 Mon Sep 17 00:00:00 2001 From: Bastian Blokland Date: Wed, 24 Jul 2019 14:57:36 +0300 Subject: [PATCH] Keep executors after work is done. Reason is that someone could have captured the sync-context and could post work later. --- src/ComponentExtensions.cs | 2 +- .../Internal/MonoBehaviourTaskRunner.cs | 75 +++++-------------- src/ComponentTask/LocalTaskRunner.cs | 8 +- tests/playmode/ComponentExtensionsTests.cs | 26 ------- 4 files changed, 20 insertions(+), 91 deletions(-) diff --git a/src/ComponentExtensions.cs b/src/ComponentExtensions.cs index 99fe446..e0e8acd 100644 --- a/src/ComponentExtensions.cs +++ b/src/ComponentExtensions.cs @@ -427,7 +427,7 @@ internal static ITaskRunner GetTaskRunnerUnchecked(Component component, TaskRunO foreach (var runner in monoBehaviourRunners) { // If there is a runner for that component then return that. - if (!runner.IsFinished && runner.RunOptions == options && runner.ComponentToFollow == component) + if (runner.RunOptions == options && runner.ComponentToFollow == component) return runner; } diff --git a/src/ComponentTask/Internal/MonoBehaviourTaskRunner.cs b/src/ComponentTask/Internal/MonoBehaviourTaskRunner.cs index c393336..345199c 100644 --- a/src/ComponentTask/Internal/MonoBehaviourTaskRunner.cs +++ b/src/ComponentTask/Internal/MonoBehaviourTaskRunner.cs @@ -18,61 +18,33 @@ public MonoBehaviourTaskRunner() public Component ComponentToFollow { get; set; } - public bool IsFinished { get; private set; } + public Task StartTask(Func taskCreator) => + this.taskRunner.StartTask(taskCreator); - public Task StartTask(Func taskCreator) - { - System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner"); - return this.taskRunner.StartTask(taskCreator); - } + public Task StartTask(Func taskCreator) => + this.taskRunner.StartTask(taskCreator); - public Task StartTask(Func taskCreator) - { - System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner"); - return this.taskRunner.StartTask(taskCreator); - } + public Task StartTask(Func taskCreator, TIn data) => + this.taskRunner.StartTask(taskCreator, data); - public Task StartTask(Func taskCreator, TIn data) - { - System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner"); - return this.taskRunner.StartTask(taskCreator, data); - } + public Task StartTask(Func taskCreator, TIn data) => + this.taskRunner.StartTask(taskCreator, data); - public Task StartTask(Func taskCreator, TIn data) - { - System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner"); - return this.taskRunner.StartTask(taskCreator, data); - } + public Task StartTask(Func> taskCreator) => + this.taskRunner.StartTask(taskCreator); - public Task StartTask(Func> taskCreator) - { - System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner"); - return this.taskRunner.StartTask(taskCreator); - } + public Task StartTask(Func> taskCreator) => + this.taskRunner.StartTask(taskCreator); - public Task StartTask(Func> taskCreator) - { - System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner"); - return this.taskRunner.StartTask(taskCreator); - } + public Task StartTask(Func> taskCreator, TIn data) => + this.taskRunner.StartTask(taskCreator, data); - public Task StartTask(Func> taskCreator, TIn data) - { - System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner"); - return this.taskRunner.StartTask(taskCreator, data); - } - - public Task StartTask(Func> taskCreator, TIn data) - { - System.Diagnostics.Debug.Assert(!this.IsFinished, "Task was started on already finished runner"); - return this.taskRunner.StartTask(taskCreator, data); - } + public Task StartTask(Func> taskCreator, TIn data) => + this.taskRunner.StartTask(taskCreator, data); // Dynamically called from the Unity runtime. private void LateUpdate() { - System.Diagnostics.Debug.Assert(!this.IsFinished, "Already finished runner was updated"); - // Check if we have a 'ComponentToFollow' assigned. if (this.ComponentToFollow is null) { @@ -106,20 +78,9 @@ private void LateUpdate() // Dynamically called from the Unity runtime. private void OnDestroy() => this.taskRunner.Dispose(); - private void Execute() - { - var workRemaining = this.taskRunner.Execute(); - - // If we've finished all the work then destroy ourselves. - if (!workRemaining) - this.Destroy(); - } + private void Execute() => this.taskRunner.Execute(); - private void Destroy() - { - this.IsFinished = true; - UnityEngine.Object.Destroy(this); - } + private void Destroy() => UnityEngine.Object.Destroy(this); void IExceptionHandler.Handle(Exception exception) { diff --git a/src/ComponentTask/LocalTaskRunner.cs b/src/ComponentTask/LocalTaskRunner.cs index 541a790..e92a16a 100644 --- a/src/ComponentTask/LocalTaskRunner.cs +++ b/src/ComponentTask/LocalTaskRunner.cs @@ -169,13 +169,11 @@ public Task StartTask(Func> /// /// Execute all the work that was 'scheduled' by the tasks running on this runner. /// - /// True if still running work, False if all work has finished. - public bool Execute() + public void Execute() { if (this.isDisposed) throw new ObjectDisposedException(nameof(LocalTaskRunner)); - bool tasksRemaining; try { // Execute all the work that was scheduled on this runner. @@ -194,12 +192,8 @@ public bool Execute() if (this.runningTasks[i].IsFinished) this.runningTasks.RemoveAt(i); } - - tasksRemaining = this.runningTasks.Count > 0; } } - - return tasksRemaining; } /// diff --git a/tests/playmode/ComponentExtensionsTests.cs b/tests/playmode/ComponentExtensionsTests.cs index 10c0877..377f59a 100644 --- a/tests/playmode/ComponentExtensionsTests.cs +++ b/tests/playmode/ComponentExtensionsTests.cs @@ -372,32 +372,6 @@ async Task TestAsync() } } - [UnityTest] - public IEnumerator RunnerDestroysItselfWhenWorkIsDone() - { - var go = new GameObject("TestGameObject"); - var comp = go.AddComponent(); - comp.StartTask(TestAsync); - - // Assert that runner was created. - Assert.AreEqual(2, go.GetComponents().Length); - - // Wait for work to finish. - yield return null; - - // Assert that runner has destroyed itself. - Assert.AreEqual(1, go.GetComponents().Length); - - // Cleanup. - yield return null; - Object.Destroy(go); - - async Task TestAsync() - { - await Task.Yield(); - } - } - [UnityTest] public IEnumerator ThrowsWhenCalledFromNonUnityThread() {