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