From 71f6d7830d18fe7d653c44f5f691c4ee8034e13b Mon Sep 17 00:00:00 2001 From: slothdpal <16717792+SlothDpal@users.noreply.github.com> Date: Mon, 22 Sep 2025 21:42:13 +0300 Subject: [PATCH 1/3] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B5=D0=BA=20=D0=B8?= =?UTF-8?q?=D0=B7=20=D1=81=D1=82=D0=B0=D1=80=D0=BE=20=D1=81=D0=B1=D0=BE?= =?UTF-8?q?=D1=80=D0=BA=D0=B8=20=D0=B2=20=D0=BD=D0=BE=D0=B2=D1=83=D1=8E=20?= =?UTF-8?q?=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20settings.upgrade?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.config | 3 +++ Form1.cs | 20 +++++++++++++++++++- Process Auto Relaunch.csproj | 5 +---- Properties/AssemblyInfo.cs | 6 +++--- Properties/Settings.Designer.cs | 16 ++++++++++++++-- Properties/Settings.settings | 3 +++ 6 files changed, 43 insertions(+), 10 deletions(-) diff --git a/App.config b/App.config index 379efdc..1da09fe 100644 --- a/App.config +++ b/App.config @@ -47,6 +47,9 @@ True + + True + diff --git a/Form1.cs b/Form1.cs index 1d9b0e8..a29e69d 100644 --- a/Form1.cs +++ b/Form1.cs @@ -15,7 +15,7 @@ using RelaunchProcess; using System.Timers; using System.Threading.Tasks; using System.Runtime.CompilerServices; - +using System.Configuration; namespace Process_Auto_Relaunch { @@ -47,6 +47,24 @@ namespace Process_Auto_Relaunch public Form1() { InitializeComponent(); + if (Settings.Default.upgradeSettings) + { + Debug.WriteLine("Обновление настроек."); + try + { + Settings.Default.Upgrade(); + } + catch (ConfigurationErrorsException ex) + { + Debug.WriteLine($"Ошибка обновления настроек: {ex.Message}"); + Settings.Default.Reset(); + } + finally + { + Settings.Default.upgradeSettings = false; + Settings.Default.Save(); + } + } this.updateLogDelegate = this.UpdateStatus; this.updateLogDelegate += this.SendDiscordMessage; this.updateLogDelegate += this.HistoryLog; diff --git a/Process Auto Relaunch.csproj b/Process Auto Relaunch.csproj index d9789f4..4bd7346 100644 --- a/Process Auto Relaunch.csproj +++ b/Process Auto Relaunch.csproj @@ -82,14 +82,11 @@ true - - False - .\CSharpDiscordWebhook.dll - packages\Newtonsoft.Json.13.0.4\lib\net45\Newtonsoft.Json.dll + diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index a125594..fe55b4e 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -29,7 +29,7 @@ using System.Runtime.InteropServices; // Номер сборки // Редакция // -[assembly: AssemblyVersion("1.6.0.0")] -[assembly: AssemblyFileVersion("1.6.0.0")] +[assembly: AssemblyVersion("1.6.0.21")] +[assembly: AssemblyFileVersion("1.6.0.21")] -[assembly: AssemblyInformationalVersion("1.6.0.0")] \ No newline at end of file +[assembly: AssemblyInformationalVersion("1.6.0.21")] \ No newline at end of file diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs index 7be96f2..b9a3b21 100644 --- a/Properties/Settings.Designer.cs +++ b/Properties/Settings.Designer.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Этот код создан программой. // Исполняемая версия:4.0.30319.42000 @@ -12,7 +12,7 @@ namespace RelaunchProcess.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -179,5 +179,17 @@ namespace RelaunchProcess.Properties { this["closeFreezeProcess"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool upgradeSettings { + get { + return ((bool)(this["upgradeSettings"])); + } + set { + this["upgradeSettings"] = value; + } + } } } diff --git a/Properties/Settings.settings b/Properties/Settings.settings index aa69502..71525a6 100644 --- a/Properties/Settings.settings +++ b/Properties/Settings.settings @@ -41,5 +41,8 @@ True + + True + \ No newline at end of file From f458a2d5e5dff24158df27eb55258c35a219025f Mon Sep 17 00:00:00 2001 From: slothdpal <16717792+SlothDpal@users.noreply.github.com> Date: Tue, 23 Sep 2025 00:57:17 +0300 Subject: [PATCH 2/3] discord queue upgrade --- Discord/DiscordWebHook.cs | 47 ++++++++++++++++++++++++++++++-------- Form1.cs | 1 + Properties/AssemblyInfo.cs | 6 ++--- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/Discord/DiscordWebHook.cs b/Discord/DiscordWebHook.cs index 5a64dbe..f44c99d 100644 --- a/Discord/DiscordWebHook.cs +++ b/Discord/DiscordWebHook.cs @@ -13,12 +13,17 @@ namespace Discord.Webhook { public string Url { get; set; } - private UInt64 queueNum = 0; + private UInt64 totalMessages = 0; private readonly ConcurrentQueue<(UInt64 num, DiscordMessage message, FileInfo[] files)> _queue = new ConcurrentQueue<(UInt64 num, DiscordMessage, FileInfo[])>(); private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); private bool _isProcessing; + private CancellationTokenSource _cts = new CancellationTokenSource(); - public async Task SendAsync(DiscordMessage message, params FileInfo[] files) + public UInt64 GetTotalMessages() => totalMessages; + public int GetQueueSize() => _queue.Count; + public void CancelProcessing() => _cts.Cancel(); + + public async Task SendAsync(DiscordMessage message, params FileInfo[] files) { if (string.IsNullOrEmpty(Url)) throw new ArgumentNullException("Invalid Webhook URL."); @@ -54,46 +59,70 @@ namespace Discord.Webhook try { - var response = await client.PostAsync(Url, content); + var response = await client.PostAsync(Url, content, _cts.Token); response.EnsureSuccessStatusCode(); } catch (HttpRequestException ex) { Debug.WriteLine($"Discord webhook request failed: {ex.Message}"); + return false; + } + catch (TaskCanceledException ex) + { + Debug.WriteLine($"Discord webhook request cancelled: {ex.Message}"); + return false; } } + return true; } private async Task ProcessQueueAsync() { - while (_queue.TryDequeue(out var item)) + while (_queue.TryPeek(out var item)) { + if (_cts.Token.IsCancellationRequested) + { + Debug.WriteLine("Discord queue processing cancelled."); + break; + } await _semaphore.WaitAsync(); try { Debug.WriteLine($"Processing message {item.num}. Queue size: {_queue.Count}"); - await SendAsync(item.message, item.files); - Debug.WriteLine($"Message {item.num} sent."); + if (await SendAsync(item.message, item.files)) + { + _queue.TryDequeue(out var deqItem); + } } finally { _semaphore.Release(); } - Task.Delay(500).Wait(); + try + { + await Task.Delay(1000, _cts.Token); // Discord rate limit: 1 message per second + } + catch (TaskCanceledException) + { + Debug.WriteLine($"Discord queue processing cancelled during delay. Was {_queue.Count} messages in queue. {totalMessages} messages in session. "); + break; + } } _isProcessing = false; } public void Send(DiscordMessage message, params FileInfo[] files) { - _queue.Enqueue((queueNum++, message, files)); - Debug.WriteLine($"Message {queueNum-1} added. Queue size: {_queue.Count}"); + _queue.Enqueue((totalMessages++, message, files)); + Debug.WriteLine($"Message {totalMessages-1} added. Queue size: {_queue.Count}"); if (_isProcessing) { Debug.WriteLine("Already processing queue."); return; } Debug.WriteLine("Run ProcessQueueAsync"); + _cts.Dispose(); + _cts = new CancellationTokenSource(); _isProcessing = true; Task.Run(ProcessQueueAsync); } diff --git a/Form1.cs b/Form1.cs index a29e69d..b7ce2d5 100644 --- a/Form1.cs +++ b/Form1.cs @@ -267,6 +267,7 @@ namespace Process_Auto_Relaunch /// private void Form1_FormClosing(object sender, FormClosingEventArgs e) { + dwhHook.CancelProcessing(); Settings.Default.Save(); Status("Наблюдение отменено - приложение закрыто.", NotifyLevel.logAlways); } diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index fe55b4e..7c7afac 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -29,7 +29,7 @@ using System.Runtime.InteropServices; // Номер сборки // Редакция // -[assembly: AssemblyVersion("1.6.0.21")] -[assembly: AssemblyFileVersion("1.6.0.21")] +[assembly: AssemblyVersion("1.6.0.32")] +[assembly: AssemblyFileVersion("1.6.0.32")] -[assembly: AssemblyInformationalVersion("1.6.0.21")] \ No newline at end of file +[assembly: AssemblyInformationalVersion("1.6.0.32")] \ No newline at end of file From d3bb5e10f69908baaa8b13860a6ac3a0c4993e1f Mon Sep 17 00:00:00 2001 From: slothdpal <16717792+SlothDpal@users.noreply.github.com> Date: Fri, 26 Sep 2025 16:50:58 +0300 Subject: [PATCH 3/3] queue fixes --- Discord/DiscordWebHook.cs | 50 +++++++++++++++++++++++++++++++------- DiscordSettings.cs | 10 +++++++- Form1.cs | 6 ++--- Properties/AssemblyInfo.cs | 6 ++--- 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/Discord/DiscordWebHook.cs b/Discord/DiscordWebHook.cs index f44c99d..2c2b733 100644 --- a/Discord/DiscordWebHook.cs +++ b/Discord/DiscordWebHook.cs @@ -12,16 +12,24 @@ namespace Discord.Webhook public class DiscordWebhook { public string Url { get; set; } + public int queueRetryCount = 3; + public int sendTimeoutSeconds = 5; private UInt64 totalMessages = 0; - private readonly ConcurrentQueue<(UInt64 num, DiscordMessage message, FileInfo[] files)> _queue = new ConcurrentQueue<(UInt64 num, DiscordMessage, FileInfo[])>(); + private ConcurrentQueue<(UInt64 num, DiscordMessage message, FileInfo[] files)> _queue = new ConcurrentQueue<(UInt64 num, DiscordMessage, FileInfo[])>(); private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); private bool _isProcessing; private CancellationTokenSource _cts = new CancellationTokenSource(); + private int queueErrorCounter = 0; + private int queueSuppressedCounter = 0; + private HttpRequestException lastHpptEx = null; - public UInt64 GetTotalMessages() => totalMessages; - public int GetQueueSize() => _queue.Count; + public UInt64 TotalMessages => totalMessages; + public int QueueSize => _queue.Count; public void CancelProcessing() => _cts.Cancel(); + public int ErrorCount => queueErrorCounter; + public bool IsProcessing => _isProcessing; + public HttpRequestException LastHpptEx => lastHpptEx; public async Task SendAsync(DiscordMessage message, params FileInfo[] files) { @@ -30,7 +38,7 @@ namespace Discord.Webhook string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x"); - using (var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(30) }) + using (var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(sendTimeoutSeconds) }) using (var content = new MultipartFormDataContent(boundary)) { // Добавляем JSON payload @@ -64,12 +72,13 @@ namespace Discord.Webhook } catch (HttpRequestException ex) { - Debug.WriteLine($"Discord webhook request failed: {ex.Message}"); + Debug.WriteLine($"SendAsync: Discord webhook request failed: {ex.Message}"); + lastHpptEx = ex; return false; } catch (TaskCanceledException ex) { - Debug.WriteLine($"Discord webhook request cancelled: {ex.Message}"); + Debug.WriteLine($"SendAsync: Discord webhook request cancelled: {ex.Message}"); return false; } } @@ -78,20 +87,34 @@ namespace Discord.Webhook private async Task ProcessQueueAsync() { + queueErrorCounter = 0; + while (_queue.TryPeek(out var item)) { if (_cts.Token.IsCancellationRequested) { - Debug.WriteLine("Discord queue processing cancelled."); + Debug.WriteLine("ProcessQueueAsync: Discord queue processing cancelled."); break; } await _semaphore.WaitAsync(); try { - Debug.WriteLine($"Processing message {item.num}. Queue size: {_queue.Count}"); + Debug.WriteLine($"ProcessQueueAsync: Processing message {item.num}. Queue size: {_queue.Count}"); if (await SendAsync(item.message, item.files)) { _queue.TryDequeue(out var deqItem); + queueErrorCounter = 0; + } + else + { + queueErrorCounter++; + if (queueErrorCounter == queueRetryCount) + { + _queue.TryDequeue(out var deqItem); + queueErrorCounter = 0; + queueSuppressedCounter++; + Debug.WriteLine($"ProcessQueueAsync: Message dropped. Total messages dropped:{queueSuppressedCounter}. Queue size: {_queue.Count}."); + } } } finally @@ -104,10 +127,18 @@ namespace Discord.Webhook } catch (TaskCanceledException) { - Debug.WriteLine($"Discord queue processing cancelled during delay. Was {_queue.Count} messages in queue. {totalMessages} messages in session. "); + Debug.WriteLine($"ProcessQueueAsync: Discord queue processing cancelled during delay. Was {_queue.Count} messages in queue. {totalMessages} messages in session. "); break; } } + if ( _cts.IsCancellationRequested) + { + Debug.WriteLine($"ProcessQueueAsync: Discord queue processing cancelled. Was {_queue.Count} messages in queue."); + Debug.WriteLine("Clearing queue."); + var _newqueue = new ConcurrentQueue<(UInt64 num, DiscordMessage, FileInfo[])>(); + Interlocked.Exchange(ref _queue, _newqueue); + } + Debug.WriteLine($"ProcessQueueAsync: Discord queue processing finished."); _isProcessing = false; } @@ -125,6 +156,7 @@ namespace Discord.Webhook _cts = new CancellationTokenSource(); _isProcessing = true; Task.Run(ProcessQueueAsync); + return; } } } \ No newline at end of file diff --git a/DiscordSettings.cs b/DiscordSettings.cs index 8560bc0..8474c7e 100644 --- a/DiscordSettings.cs +++ b/DiscordSettings.cs @@ -9,15 +9,19 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; +using Process_Auto_Relaunch; using RelaunchProcess.Properties; namespace RelaunchProcess { public partial class WebhookSettings : Form { - public WebhookSettings() + private Form1 parent; + + public WebhookSettings(Form1 _parent) { InitializeComponent(); + parent = _parent; RestoreSettings(); } @@ -64,6 +68,10 @@ namespace RelaunchProcess { chbxDiscordEnabled.Checked = false; } + if (!chbxDiscordEnabled.Checked) + { + parent.dwhHook.CancelProcessing(); + } SaveSettings(); DialogResult = DialogResult.OK; Close(); diff --git a/Form1.cs b/Form1.cs index b7ce2d5..4027fbc 100644 --- a/Form1.cs +++ b/Form1.cs @@ -32,7 +32,7 @@ namespace Process_Auto_Relaunch } private delegate void UpdateLogDelegate(string text, NotifyLevel level = NotifyLevel.logUpdateStatus); private readonly UpdateLogDelegate updateLogDelegate; - private DiscordWebhook dwhHook; + public DiscordWebhook dwhHook; private DiscordMessage dwhMessage; private Process WatchedProcess; private double cpuLastTime = 0; @@ -268,8 +268,8 @@ namespace Process_Auto_Relaunch private void Form1_FormClosing(object sender, FormClosingEventArgs e) { dwhHook.CancelProcessing(); - Settings.Default.Save(); Status("Наблюдение отменено - приложение закрыто.", NotifyLevel.logAlways); + Settings.Default.Save(); } private bool ProcessByNameIsRuning(string name) @@ -495,7 +495,7 @@ namespace Process_Auto_Relaunch private void webhookDiscordToolStripMenuItem_Click(object sender, EventArgs e) { WebhookSettings discordSettings; - discordSettings = new WebhookSettings(); + discordSettings = new WebhookSettings(this); discordSettings.ShowDialog(this); discordSettings.Dispose(); } diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 7c7afac..fb42d28 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -29,7 +29,7 @@ using System.Runtime.InteropServices; // Номер сборки // Редакция // -[assembly: AssemblyVersion("1.6.0.32")] -[assembly: AssemblyFileVersion("1.6.0.32")] +[assembly: AssemblyVersion("1.6.1.2")] +[assembly: AssemblyFileVersion("1.6.1.2")] -[assembly: AssemblyInformationalVersion("1.6.0.32")] \ No newline at end of file +[assembly: AssemblyInformationalVersion("1.6.1.2")] \ No newline at end of file