mirror of
https://github.com/Stone-Red-Code/DesktopMagic.git
synced 2026-09-04 08:56:15 +02:00
Add cancellation support to AsyncPlugin methods
This commit is contained in:
@@ -7,6 +7,7 @@ using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DesktopMagic.BuiltInPlugins;
|
||||
@@ -46,7 +47,7 @@ public class WeatherPlugin : AsyncPlugin
|
||||
private string lastUpdated = "";
|
||||
private bool isLoading = false;
|
||||
|
||||
public override async void Start()
|
||||
public override async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (DesktopMagic)");
|
||||
|
||||
@@ -74,7 +75,7 @@ public class WeatherPlugin : AsyncPlugin
|
||||
};
|
||||
}
|
||||
|
||||
public override async Task<Bitmap?> MainAsync()
|
||||
public override async Task<Bitmap?> MainAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
// Periodic background update
|
||||
if (!isLoading && cachedLat != null && cachedLon != null)
|
||||
|
||||
@@ -37,6 +37,8 @@ public partial class PluginWindow : Window, IPluginWindow
|
||||
private Plugin? pluginClassInstance;
|
||||
private readonly AssemblyLoadContext assemblyLoadContext;
|
||||
|
||||
private CancellationTokenSource? pluginCancellationTokenSource;
|
||||
|
||||
public bool IsRunning { get; private set; } = true;
|
||||
public PluginMetadata PluginMetadata { get; private set; }
|
||||
public string PluginFolderPath { get; private set; }
|
||||
@@ -315,6 +317,12 @@ public partial class PluginWindow : Window, IPluginWindow
|
||||
updateTimer.Elapsed += UpdateTimer_Elapsed;
|
||||
|
||||
pluginClassInstance.Start();
|
||||
if (pluginClassInstance is AsyncPlugin asyncPluginStart)
|
||||
{
|
||||
pluginCancellationTokenSource?.Dispose();
|
||||
pluginCancellationTokenSource = new CancellationTokenSource();
|
||||
await asyncPluginStart.StartAsync(pluginCancellationTokenSource.Token);
|
||||
}
|
||||
UpdatePluginWindow();
|
||||
await Dispatcher.InvokeAsync(ThemeChanged);
|
||||
|
||||
@@ -602,7 +610,8 @@ public partial class PluginWindow : Window, IPluginWindow
|
||||
|
||||
if (pluginClassInstance is AsyncPlugin asyncPlugin)
|
||||
{
|
||||
result = await asyncPlugin.MainAsync();
|
||||
CancellationToken token = pluginCancellationTokenSource?.Token ?? CancellationToken.None;
|
||||
result = await asyncPlugin.MainAsync(token);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -678,6 +687,20 @@ public partial class PluginWindow : Window, IPluginWindow
|
||||
|
||||
try
|
||||
{
|
||||
pluginCancellationTokenSource?.Cancel();
|
||||
|
||||
if (pluginClassInstance is AsyncPlugin asyncPluginStop)
|
||||
{
|
||||
try
|
||||
{
|
||||
_ = asyncPluginStop.StopAsync(pluginCancellationTokenSource?.Token ?? CancellationToken.None);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
App.Logger.LogError($"\"{PluginMetadata.Name}\" - {ex}", source: "Plugin");
|
||||
}
|
||||
}
|
||||
|
||||
if (pluginClassInstance is not null)
|
||||
{
|
||||
SaveState(pluginClassInstance);
|
||||
@@ -690,6 +713,9 @@ public partial class PluginWindow : Window, IPluginWindow
|
||||
}
|
||||
|
||||
assemblyLoadContext.Unload();
|
||||
|
||||
pluginCancellationTokenSource?.Dispose();
|
||||
pluginCancellationTokenSource = null;
|
||||
}
|
||||
|
||||
#region Window Events
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DesktopMagic.Api;
|
||||
@@ -15,11 +16,23 @@ namespace DesktopMagic.Api;
|
||||
/// intervals, and configuration changes as needed.</remarks>
|
||||
public abstract class AsyncPlugin : Plugin
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs once when the plugin gets activated. Override for async initialization.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Token signaled when the host requests cancellation.</param>
|
||||
public virtual Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs once when the plugin gets deactivated. Override for async cleanup.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Token signaled when the host requests cancellation.</param>
|
||||
public virtual Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the <see cref="Plugin.UpdateInterval"/> elapses.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract Task<Bitmap?> MainAsync();
|
||||
public abstract Task<Bitmap?> MainAsync(CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// This method should not be called directly! Override and use <see cref="MainAsync"/> for asynchronous plugin operations.
|
||||
|
||||
Reference in New Issue
Block a user