From acc71495d1f3cb997aa5f691df1bdbde2bdb22f9 Mon Sep 17 00:00:00 2001 From: OsakaRuma Date: Sun, 15 Sep 2024 19:17:56 +0800 Subject: [PATCH] fix: fixed the bug that method `CurrentTaskFinished` was executed multiple times by multiple threads (#1084) * fixed the bug that method `CurrentTaskFinished` was executed multiple times by multiple threads (#1083) (#1082) Signed-off-by: OsakaRuma * handling exception, deleted voice code Signed-off-by: OsakaRuma * fixed typo of variable name Signed-off-by: OsakaRuma * fixed typo in variable name Signed-off-by: OsakaRuma * fixed a bug where only the first step of the task could be run if there were multiple steps of the task when installing the game Signed-off-by: OsakaRuma --------- Signed-off-by: OsakaRuma --- .../Services/Download/InstallGameService.cs | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/Starward/Services/Download/InstallGameService.cs b/src/Starward/Services/Download/InstallGameService.cs index dcfb4f570..8a8bd84a3 100644 --- a/src/Starward/Services/Download/InstallGameService.cs +++ b/src/Starward/Services/Download/InstallGameService.cs @@ -627,6 +627,8 @@ public void ClearState() protected void StartTask(InstallGameState state) { + if (_concurrentExecuteThreadCount > 0) return; + if (state is InstallGameState.Download) { if (InstallTask is InstallGameTask.HardLink) @@ -713,10 +715,26 @@ protected void StartTask(InstallGameState state) _finishBytes = 0; } State = state; - _cancellationTokenSource = new CancellationTokenSource(); - for (int i = 0; i < Environment.ProcessorCount; i++) + + _ = RunTasksAsync(); //不需要ConfigureAwait,因为返回值丢弃,且无需调用“.GetAwaiter().OnCompleted()” + return; + + async Task RunTasksAsync() { - _ = ExecuteTaskItemAsync(_cancellationTokenSource.Token).ConfigureAwait(false); + _cancellationTokenSource = new CancellationTokenSource(); + var tasks = new Task[Environment.ProcessorCount]; + for (int i = 0; i < Environment.ProcessorCount; i++) + { + tasks[i] = ExecuteTaskItemAsync(_cancellationTokenSource.Token); + } + try + { + await Task.WhenAll(tasks).ConfigureAwait(false); + } + finally + { + CurrentTaskFinished(); + } } } @@ -1106,11 +1124,6 @@ protected async Task ExecuteTaskItemAsync(CancellationToken cancellationToken = try { Interlocked.Increment(ref _concurrentExecuteThreadCount); - if (_concurrentExecuteThreadCount > Environment.ProcessorCount) - { - return; - } - while (_installItemQueue.TryDequeue(out InstallGameItem? item)) { try @@ -1161,10 +1174,6 @@ protected async Task ExecuteTaskItemAsync(CancellationToken cancellationToken = finally { Interlocked.Decrement(ref _concurrentExecuteThreadCount); - if (_concurrentExecuteThreadCount == 0) - { - CurrentTaskFinished(); - } } }