From 7dc9fbd8ff7fb0ebd500befef9df7e4339d89cd9 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Mon, 10 Feb 2025 10:08:03 +0800 Subject: [PATCH] Improved and optimized speedtest --- v2rayN/ServiceLib/Enums/EMsgCommand.cs | 5 +- .../ServiceLib/Services/SpeedtestService.cs | 66 ++++++++++--------- .../ViewModels/ProfilesViewModel.cs | 9 ++- 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/v2rayN/ServiceLib/Enums/EMsgCommand.cs b/v2rayN/ServiceLib/Enums/EMsgCommand.cs index 86d5213e..9bf844ff 100644 --- a/v2rayN/ServiceLib/Enums/EMsgCommand.cs +++ b/v2rayN/ServiceLib/Enums/EMsgCommand.cs @@ -1,4 +1,4 @@ -namespace ServiceLib.Enums +namespace ServiceLib.Enums { public enum EMsgCommand { @@ -6,7 +6,6 @@ SendMsgView, SendSnackMsg, RefreshProfiles, - StopSpeedtest, AppExit } -} \ No newline at end of file +} diff --git a/v2rayN/ServiceLib/Services/SpeedtestService.cs b/v2rayN/ServiceLib/Services/SpeedtestService.cs index be08cbdb..a978f2f5 100644 --- a/v2rayN/ServiceLib/Services/SpeedtestService.cs +++ b/v2rayN/ServiceLib/Services/SpeedtestService.cs @@ -1,34 +1,47 @@ +using System.Collections.Concurrent; using System.Diagnostics; using System.Net; using System.Net.Sockets; -using ReactiveUI; namespace ServiceLib.Services { public class SpeedtestService { + private static readonly string _tag = "SpeedtestService"; private Config? _config; private Action? _updateFunc; + private static readonly ConcurrentBag _lstExitLoop = new(); - private bool _exitLoop = false; - private static readonly string _tag = "SpeedtestService"; - - public SpeedtestService(Config config, ESpeedActionType actionType, List selecteds, Action updateFunc) + public SpeedtestService(Config config, Action updateFunc) { _config = config; _updateFunc = updateFunc; + } - MessageBus.Current.Listen(EMsgCommand.StopSpeedtest.ToString()).Subscribe(ExitLoop); - + public void RunLoop(ESpeedActionType actionType, List selecteds) + { Task.Run(async () => { + var exitLoopKey = Utils.GetGuid(false); + _lstExitLoop.Add(exitLoopKey); + var lstSelected = GetClearItem(actionType, selecteds); - await RunAsync(actionType, lstSelected); + await RunAsync(actionType, lstSelected, exitLoopKey); UpdateFunc("", ResUI.SpeedtestingCompleted); }); } - private async Task RunAsync(ESpeedActionType actionType, List lstSelected, int pageSize = 0) + public void ExitLoop() + { + if (_lstExitLoop.Count > 0) + { + UpdateFunc("", ResUI.SpeedtestingStop); + + _lstExitLoop.Clear(); + } + } + + private async Task RunAsync(ESpeedActionType actionType, List lstSelected, string exitLoopKey, int pageSize = 0) { if (actionType == ESpeedActionType.Tcping) { @@ -47,9 +60,9 @@ namespace ServiceLib.Services { var ret = actionType switch { - ESpeedActionType.Realping => await RunRealPingAsync(lst), - ESpeedActionType.Speedtest => await RunSpeedTestAsync(lst), - ESpeedActionType.Mixedtest => await RunMixedTestAsync(lst), + ESpeedActionType.Realping => await RunRealPingAsync(lst, exitLoopKey), + ESpeedActionType.Speedtest => await RunSpeedTestAsync(lst, exitLoopKey), + ESpeedActionType.Mixedtest => await RunMixedTestAsync(lst, exitLoopKey), _ => true }; if (ret == false) @@ -63,14 +76,14 @@ namespace ServiceLib.Services var pageSizeNext = pageSize / 2; if (lstFailed.Count > 0 && pageSizeNext > 0) { - if (_exitLoop) + if (_lstExitLoop.Any(p => p == exitLoopKey) == false) { UpdateFunc("", ResUI.SpeedtestingSkip); return; } UpdateFunc("", string.Format(ResUI.SpeedtestingTestFailedPart, lstFailed.Count)); - await RunAsync(actionType, lstFailed, pageSizeNext); + await RunAsync(actionType, lstFailed, exitLoopKey, pageSizeNext); } } @@ -143,14 +156,6 @@ namespace ServiceLib.Services return lstTest; } - private void ExitLoop(string x) - { - if (_exitLoop) - return; - _exitLoop = true; - UpdateFunc("", ResUI.SpeedtestingStop); - } - private async Task RunTcpingAsync(List selecteds) { try @@ -190,7 +195,7 @@ namespace ServiceLib.Services } } - private async Task RunRealPingAsync(List selecteds) + private async Task RunRealPingAsync(List selecteds, string exitLoopKey) { var pid = -1; try @@ -249,7 +254,7 @@ namespace ServiceLib.Services return true; } - private async Task RunSpeedTestAsync(List selecteds) + private async Task RunSpeedTestAsync(List selecteds, string exitLoopKey) { var pid = -1; pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds); @@ -265,11 +270,12 @@ namespace ServiceLib.Services foreach (var it in selecteds) { - if (_exitLoop) + if (_lstExitLoop.Any(p => p == exitLoopKey) == false) { UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip); continue; } + if (!it.AllowTest) { continue; @@ -311,7 +317,7 @@ namespace ServiceLib.Services return true; } - private async Task RunSpeedTestMulti(List selecteds) + private async Task RunSpeedTestMultiAsync(List selecteds, string exitLoopKey) { var pid = -1; pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds); @@ -327,7 +333,7 @@ namespace ServiceLib.Services foreach (var it in selecteds) { - if (_exitLoop) + if (_lstExitLoop.Any(p => p == exitLoopKey) == false) { UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip); continue; @@ -376,9 +382,9 @@ namespace ServiceLib.Services return true; } - private async Task RunMixedTestAsync(List selecteds) + private async Task RunMixedTestAsync(List selecteds, string exitLoopKey) { - var ret = await RunRealPingAsync(selecteds); + var ret = await RunRealPingAsync(selecteds, exitLoopKey); if (ret == false) { return false; @@ -386,7 +392,7 @@ namespace ServiceLib.Services await Task.Delay(1000); - var ret2 = await RunSpeedTestMulti(selecteds); + var ret2 = await RunSpeedTestMultiAsync(selecteds, exitLoopKey); if (ret2 == false) { return false; diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs index bfaadf0b..e3106307 100644 --- a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs @@ -16,6 +16,7 @@ namespace ServiceLib.ViewModels private List _lstProfile; private string _serverFilter = string.Empty; private Dictionary _dicHeaderSort = new(); + private SpeedtestService? _speedtestService; #endregion private prop @@ -722,15 +723,13 @@ namespace ServiceLib.ViewModels return; } - _ = new SpeedtestService(_config, actionType, lstSelecteds, (SpeedTestResult result) => - { - _updateView?.Invoke(EViewAction.DispatcherSpeedTest, result); - }); + _speedtestService ??= new SpeedtestService(_config, (SpeedTestResult result) => _updateView?.Invoke(EViewAction.DispatcherSpeedTest, result)); + _speedtestService?.RunLoop(actionType, lstSelecteds); } public void ServerSpeedtestStop() { - MessageBus.Current.SendMessage("", EMsgCommand.StopSpeedtest.ToString()); + _speedtestService?.ExitLoop(); } private async Task Export2ClientConfigAsync(bool blClipboard)