Improved and optimized speedtest
Some checks are pending
release Linux / build (Release) (push) Waiting to run
release macOS / build (Release) (push) Waiting to run
release Windows desktop (Avalonia UI) / build (Release) (push) Waiting to run
release Windows / build (Release) (push) Waiting to run

This commit is contained in:
2dust 2025-02-10 10:08:03 +08:00
parent 31a179e647
commit 7dc9fbd8ff
3 changed files with 42 additions and 38 deletions

View file

@ -1,4 +1,4 @@
namespace ServiceLib.Enums namespace ServiceLib.Enums
{ {
public enum EMsgCommand public enum EMsgCommand
{ {
@ -6,7 +6,6 @@
SendMsgView, SendMsgView,
SendSnackMsg, SendSnackMsg,
RefreshProfiles, RefreshProfiles,
StopSpeedtest,
AppExit AppExit
} }
} }

View file

@ -1,34 +1,47 @@
using System.Collections.Concurrent;
using System.Diagnostics; using System.Diagnostics;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using ReactiveUI;
namespace ServiceLib.Services namespace ServiceLib.Services
{ {
public class SpeedtestService public class SpeedtestService
{ {
private static readonly string _tag = "SpeedtestService";
private Config? _config; private Config? _config;
private Action<SpeedTestResult>? _updateFunc; private Action<SpeedTestResult>? _updateFunc;
private static readonly ConcurrentBag<string> _lstExitLoop = new();
private bool _exitLoop = false; public SpeedtestService(Config config, Action<SpeedTestResult> updateFunc)
private static readonly string _tag = "SpeedtestService";
public SpeedtestService(Config config, ESpeedActionType actionType, List<ProfileItem> selecteds, Action<SpeedTestResult> updateFunc)
{ {
_config = config; _config = config;
_updateFunc = updateFunc; _updateFunc = updateFunc;
}
MessageBus.Current.Listen<string>(EMsgCommand.StopSpeedtest.ToString()).Subscribe(ExitLoop); public void RunLoop(ESpeedActionType actionType, List<ProfileItem> selecteds)
{
Task.Run(async () => Task.Run(async () =>
{ {
var exitLoopKey = Utils.GetGuid(false);
_lstExitLoop.Add(exitLoopKey);
var lstSelected = GetClearItem(actionType, selecteds); var lstSelected = GetClearItem(actionType, selecteds);
await RunAsync(actionType, lstSelected); await RunAsync(actionType, lstSelected, exitLoopKey);
UpdateFunc("", ResUI.SpeedtestingCompleted); UpdateFunc("", ResUI.SpeedtestingCompleted);
}); });
} }
private async Task RunAsync(ESpeedActionType actionType, List<ServerTestItem> lstSelected, int pageSize = 0) public void ExitLoop()
{
if (_lstExitLoop.Count > 0)
{
UpdateFunc("", ResUI.SpeedtestingStop);
_lstExitLoop.Clear();
}
}
private async Task RunAsync(ESpeedActionType actionType, List<ServerTestItem> lstSelected, string exitLoopKey, int pageSize = 0)
{ {
if (actionType == ESpeedActionType.Tcping) if (actionType == ESpeedActionType.Tcping)
{ {
@ -47,9 +60,9 @@ namespace ServiceLib.Services
{ {
var ret = actionType switch var ret = actionType switch
{ {
ESpeedActionType.Realping => await RunRealPingAsync(lst), ESpeedActionType.Realping => await RunRealPingAsync(lst, exitLoopKey),
ESpeedActionType.Speedtest => await RunSpeedTestAsync(lst), ESpeedActionType.Speedtest => await RunSpeedTestAsync(lst, exitLoopKey),
ESpeedActionType.Mixedtest => await RunMixedTestAsync(lst), ESpeedActionType.Mixedtest => await RunMixedTestAsync(lst, exitLoopKey),
_ => true _ => true
}; };
if (ret == false) if (ret == false)
@ -63,14 +76,14 @@ namespace ServiceLib.Services
var pageSizeNext = pageSize / 2; var pageSizeNext = pageSize / 2;
if (lstFailed.Count > 0 && pageSizeNext > 0) if (lstFailed.Count > 0 && pageSizeNext > 0)
{ {
if (_exitLoop) if (_lstExitLoop.Any(p => p == exitLoopKey) == false)
{ {
UpdateFunc("", ResUI.SpeedtestingSkip); UpdateFunc("", ResUI.SpeedtestingSkip);
return; return;
} }
UpdateFunc("", string.Format(ResUI.SpeedtestingTestFailedPart, lstFailed.Count)); 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; return lstTest;
} }
private void ExitLoop(string x)
{
if (_exitLoop)
return;
_exitLoop = true;
UpdateFunc("", ResUI.SpeedtestingStop);
}
private async Task RunTcpingAsync(List<ServerTestItem> selecteds) private async Task RunTcpingAsync(List<ServerTestItem> selecteds)
{ {
try try
@ -190,7 +195,7 @@ namespace ServiceLib.Services
} }
} }
private async Task<bool> RunRealPingAsync(List<ServerTestItem> selecteds) private async Task<bool> RunRealPingAsync(List<ServerTestItem> selecteds, string exitLoopKey)
{ {
var pid = -1; var pid = -1;
try try
@ -249,7 +254,7 @@ namespace ServiceLib.Services
return true; return true;
} }
private async Task<bool> RunSpeedTestAsync(List<ServerTestItem> selecteds) private async Task<bool> RunSpeedTestAsync(List<ServerTestItem> selecteds, string exitLoopKey)
{ {
var pid = -1; var pid = -1;
pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds); pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds);
@ -265,11 +270,12 @@ namespace ServiceLib.Services
foreach (var it in selecteds) foreach (var it in selecteds)
{ {
if (_exitLoop) if (_lstExitLoop.Any(p => p == exitLoopKey) == false)
{ {
UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip); UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip);
continue; continue;
} }
if (!it.AllowTest) if (!it.AllowTest)
{ {
continue; continue;
@ -311,7 +317,7 @@ namespace ServiceLib.Services
return true; return true;
} }
private async Task<bool> RunSpeedTestMulti(List<ServerTestItem> selecteds) private async Task<bool> RunSpeedTestMultiAsync(List<ServerTestItem> selecteds, string exitLoopKey)
{ {
var pid = -1; var pid = -1;
pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds); pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds);
@ -327,7 +333,7 @@ namespace ServiceLib.Services
foreach (var it in selecteds) foreach (var it in selecteds)
{ {
if (_exitLoop) if (_lstExitLoop.Any(p => p == exitLoopKey) == false)
{ {
UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip); UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip);
continue; continue;
@ -376,9 +382,9 @@ namespace ServiceLib.Services
return true; return true;
} }
private async Task<bool> RunMixedTestAsync(List<ServerTestItem> selecteds) private async Task<bool> RunMixedTestAsync(List<ServerTestItem> selecteds, string exitLoopKey)
{ {
var ret = await RunRealPingAsync(selecteds); var ret = await RunRealPingAsync(selecteds, exitLoopKey);
if (ret == false) if (ret == false)
{ {
return false; return false;
@ -386,7 +392,7 @@ namespace ServiceLib.Services
await Task.Delay(1000); await Task.Delay(1000);
var ret2 = await RunSpeedTestMulti(selecteds); var ret2 = await RunSpeedTestMultiAsync(selecteds, exitLoopKey);
if (ret2 == false) if (ret2 == false)
{ {
return false; return false;

View file

@ -16,6 +16,7 @@ namespace ServiceLib.ViewModels
private List<ProfileItem> _lstProfile; private List<ProfileItem> _lstProfile;
private string _serverFilter = string.Empty; private string _serverFilter = string.Empty;
private Dictionary<string, bool> _dicHeaderSort = new(); private Dictionary<string, bool> _dicHeaderSort = new();
private SpeedtestService? _speedtestService;
#endregion private prop #endregion private prop
@ -722,15 +723,13 @@ namespace ServiceLib.ViewModels
return; return;
} }
_ = new SpeedtestService(_config, actionType, lstSelecteds, (SpeedTestResult result) => _speedtestService ??= new SpeedtestService(_config, (SpeedTestResult result) => _updateView?.Invoke(EViewAction.DispatcherSpeedTest, result));
{ _speedtestService?.RunLoop(actionType, lstSelecteds);
_updateView?.Invoke(EViewAction.DispatcherSpeedTest, result);
});
} }
public void ServerSpeedtestStop() public void ServerSpeedtestStop()
{ {
MessageBus.Current.SendMessage("", EMsgCommand.StopSpeedtest.ToString()); _speedtestService?.ExitLoop();
} }
private async Task Export2ClientConfigAsync(bool blClipboard) private async Task Export2ClientConfigAsync(bool blClipboard)