Optimization and Improvement.

Changed callback from synchronous Action<bool, string> to asynchronous Func<bool, string, Task>
This commit is contained in:
2dust 2025-08-29 10:31:09 +08:00
parent f83e83de13
commit f39d966a33
3 changed files with 49 additions and 37 deletions

View file

@ -2,17 +2,18 @@ namespace ServiceLib.Handler;
public static class SubscriptionHandler public static class SubscriptionHandler
{ {
public static async Task UpdateProcess(Config config, string subId, bool blProxy, Action<bool, string> updateFunc) public static async Task UpdateProcess(Config config, string subId, bool blProxy, Func<bool, string, Task> updateFunc)
{ {
updateFunc?.Invoke(false, ResUI.MsgUpdateSubscriptionStart); await updateFunc?.Invoke(false, ResUI.MsgUpdateSubscriptionStart);
var subItem = await AppManager.Instance.SubItems(); var subItem = await AppManager.Instance.SubItems();
if (subItem is not { Count: > 0 }) if (subItem is not { Count: > 0 })
{ {
updateFunc?.Invoke(false, ResUI.MsgNoValidSubscription); await updateFunc?.Invoke(false, ResUI.MsgNoValidSubscription);
return; return;
} }
var successCount = 0;
foreach (var item in subItem) foreach (var item in subItem)
{ {
try try
@ -25,32 +26,35 @@ public static class SubscriptionHandler
var hashCode = $"{item.Remarks}->"; var hashCode = $"{item.Remarks}->";
if (item.Enabled == false) if (item.Enabled == false)
{ {
updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgSkipSubscriptionUpdate}"); await updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgSkipSubscriptionUpdate}");
continue; continue;
} }
// Create download handler // Create download handler
var downloadHandle = CreateDownloadHandler(hashCode, updateFunc); var downloadHandle = CreateDownloadHandler(hashCode, updateFunc);
updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgStartGettingSubscriptions}"); await updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgStartGettingSubscriptions}");
// Get all subscription content (main subscription + additional subscriptions) // Get all subscription content (main subscription + additional subscriptions)
var result = await DownloadAllSubscriptions(config, item, blProxy, downloadHandle); var result = await DownloadAllSubscriptions(config, item, blProxy, downloadHandle);
// Process download result // Process download result
await ProcessDownloadResult(config, item.Id, result, hashCode, updateFunc); if (await ProcessDownloadResult(config, item.Id, result, hashCode, updateFunc))
{
successCount++;
}
updateFunc?.Invoke(false, "-------------------------------------------------------"); await updateFunc?.Invoke(false, "-------------------------------------------------------");
} }
catch (Exception ex) catch (Exception ex)
{ {
var hashCode = $"{item.Remarks}->"; var hashCode = $"{item.Remarks}->";
Logging.SaveLog("UpdateSubscription", ex); Logging.SaveLog("UpdateSubscription", ex);
updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgFailedImportSubscription}: {ex.Message}"); await updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgFailedImportSubscription}: {ex.Message}");
updateFunc?.Invoke(false, "-------------------------------------------------------"); await updateFunc?.Invoke(false, "-------------------------------------------------------");
} }
} }
updateFunc?.Invoke(true, $"{ResUI.MsgUpdateSubscriptionEnd}"); await updateFunc?.Invoke(successCount > 0, $"{ResUI.MsgUpdateSubscriptionEnd}");
} }
private static bool IsValidSubscription(SubItem item, string subId) private static bool IsValidSubscription(SubItem item, string subId)
@ -76,7 +80,7 @@ public static class SubscriptionHandler
return true; return true;
} }
private static DownloadService CreateDownloadHandler(string hashCode, Action<bool, string> updateFunc) private static DownloadService CreateDownloadHandler(string hashCode, Func<bool, string, Task> updateFunc)
{ {
var downloadHandle = new DownloadService(); var downloadHandle = new DownloadService();
downloadHandle.Error += (sender2, args) => downloadHandle.Error += (sender2, args) =>
@ -181,23 +185,23 @@ public static class SubscriptionHandler
return result; return result;
} }
private static async Task ProcessDownloadResult(Config config, string id, string result, string hashCode, Action<bool, string> updateFunc) private static async Task<bool> ProcessDownloadResult(Config config, string id, string result, string hashCode, Func<bool, string, Task> updateFunc)
{ {
if (result.IsNullOrEmpty()) if (result.IsNullOrEmpty())
{ {
updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgSubscriptionDecodingFailed}"); await updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgSubscriptionDecodingFailed}");
return; return false;
} }
updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgGetSubscriptionSuccessfully}"); await updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgGetSubscriptionSuccessfully}");
// If result is too short, display content directly // If result is too short, display content directly
if (result.Length < 99) if (result.Length < 99)
{ {
updateFunc?.Invoke(false, $"{hashCode}{result}"); await updateFunc?.Invoke(false, $"{hashCode}{result}");
} }
updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgStartParsingSubscription}"); await updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgStartParsingSubscription}");
// Add servers to configuration // Add servers to configuration
var ret = await ConfigHandler.AddBatchServers(config, result, id, true); var ret = await ConfigHandler.AddBatchServers(config, result, id, true);
@ -208,9 +212,10 @@ public static class SubscriptionHandler
} }
// Update completion message // Update completion message
updateFunc?.Invoke(false, await updateFunc?.Invoke(false, ret > 0
ret > 0
? $"{hashCode}{ResUI.MsgUpdateSubscriptionEnd}" ? $"{hashCode}{ResUI.MsgUpdateSubscriptionEnd}"
: $"{hashCode}{ResUI.MsgFailedImportSubscription}"); : $"{hashCode}{ResUI.MsgFailedImportSubscription}");
return ret > 0;
} }
} }

View file

@ -4,13 +4,18 @@ public class TaskManager
{ {
private static readonly Lazy<TaskManager> _instance = new(() => new()); private static readonly Lazy<TaskManager> _instance = new(() => new());
public static TaskManager Instance => _instance.Value; public static TaskManager Instance => _instance.Value;
private Config _config;
private Func<bool, string, Task>? _updateFunc;
public void RegUpdateTask(Config config, Action<bool, string> updateFunc) public void RegUpdateTask(Config config, Func<bool, string, Task> updateFunc)
{ {
Task.Run(() => ScheduledTasks(config, updateFunc)); _config = config;
_updateFunc = updateFunc;
Task.Run(ScheduledTasks);
} }
private async Task ScheduledTasks(Config config, Action<bool, string> updateFunc) private async Task ScheduledTasks()
{ {
Logging.SaveLog("Setup Scheduled Tasks"); Logging.SaveLog("Setup Scheduled Tasks");
@ -21,14 +26,14 @@ public class TaskManager
await Task.Delay(1000 * 60); await Task.Delay(1000 * 60);
//Execute once 1 minute //Execute once 1 minute
await UpdateTaskRunSubscription(config, updateFunc); await UpdateTaskRunSubscription();
//Execute once 20 minute //Execute once 20 minute
if (numOfExecuted % 20 == 0) if (numOfExecuted % 20 == 0)
{ {
//Logging.SaveLog("Execute save config"); //Logging.SaveLog("Execute save config");
await ConfigHandler.SaveConfig(config); await ConfigHandler.SaveConfig(_config);
await ProfileExManager.Instance.SaveTo(); await ProfileExManager.Instance.SaveTo();
} }
@ -42,14 +47,14 @@ public class TaskManager
FileManager.DeleteExpiredFiles(Utils.GetTempPath(), DateTime.Now.AddMonths(-1)); FileManager.DeleteExpiredFiles(Utils.GetTempPath(), DateTime.Now.AddMonths(-1));
//Check once 1 hour //Check once 1 hour
await UpdateTaskRunGeo(config, numOfExecuted / 60, updateFunc); await UpdateTaskRunGeo(numOfExecuted / 60);
} }
numOfExecuted++; numOfExecuted++;
} }
} }
private async Task UpdateTaskRunSubscription(Config config, Action<bool, string> updateFunc) private async Task UpdateTaskRunSubscription()
{ {
var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds(); var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
var lstSubs = (await AppManager.Instance.SubItems())? var lstSubs = (await AppManager.Instance.SubItems())?
@ -66,30 +71,30 @@ public class TaskManager
foreach (var item in lstSubs) foreach (var item in lstSubs)
{ {
await SubscriptionHandler.UpdateProcess(config, item.Id, true, (success, msg) => await SubscriptionHandler.UpdateProcess(_config, item.Id, true, async (success, msg) =>
{ {
updateFunc?.Invoke(success, msg); await _updateFunc?.Invoke(success, msg);
if (success) if (success)
{ {
Logging.SaveLog($"Update subscription end. {msg}"); Logging.SaveLog($"Update subscription end. {msg}");
} }
}); });
item.UpdateTime = updateTime; item.UpdateTime = updateTime;
await ConfigHandler.AddSubItem(config, item); await ConfigHandler.AddSubItem(_config, item);
await Task.Delay(1000); await Task.Delay(1000);
} }
} }
private async Task UpdateTaskRunGeo(Config config, int hours, Action<bool, string> updateFunc) private async Task UpdateTaskRunGeo(int hours)
{ {
if (config.GuiItem.AutoUpdateInterval > 0 && hours > 0 && hours % config.GuiItem.AutoUpdateInterval == 0) if (_config.GuiItem.AutoUpdateInterval > 0 && hours > 0 && hours % _config.GuiItem.AutoUpdateInterval == 0)
{ {
Logging.SaveLog("Execute update geo files"); Logging.SaveLog("Execute update geo files");
var updateHandle = new UpdateService(); var updateHandle = new UpdateService();
await updateHandle.UpdateGeoFileAll(config, (success, msg) => await updateHandle.UpdateGeoFileAll(_config, (success, msg) =>
{ {
updateFunc?.Invoke(false, msg); _updateFunc?.Invoke(false, msg);
}); });
} }
} }

View file

@ -254,7 +254,7 @@ public class MainWindowViewModel : MyReactiveObject
} }
} }
private void UpdateTaskHandler(bool success, string msg) private async Task UpdateTaskHandler(bool success, string msg)
{ {
NoticeManager.Instance.SendMessageEx(msg); NoticeManager.Instance.SendMessageEx(msg);
if (success) if (success)
@ -263,7 +263,7 @@ public class MainWindowViewModel : MyReactiveObject
RefreshServers(); RefreshServers();
if (indexIdOld != _config.IndexId) if (indexIdOld != _config.IndexId)
{ {
_ = Reload(); await Reload();
} }
if (_config.UiItem.EnableAutoAdjustMainLvColWidth) if (_config.UiItem.EnableAutoAdjustMainLvColWidth)
{ {
@ -596,7 +596,9 @@ public class MainWindowViewModel : MyReactiveObject
Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload(); Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload();
} }
else else
{ TabMainSelectedIndex = 0; } {
TabMainSelectedIndex = 0;
}
} }
private async Task LoadCore() private async Task LoadCore()
@ -631,7 +633,7 @@ public class MainWindowViewModel : MyReactiveObject
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu(); Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
await ConfigHandler.SaveConfig(_config); await ConfigHandler.SaveConfig(_config);
await new UpdateService().UpdateGeoFileAll(_config, UpdateTaskHandler); //TODO await new UpdateService().UpdateGeoFileAll(_config, UpdateTaskHandler);
await Reload(); await Reload();
} }