Squash that async bug for good

This commit is contained in:
Alexander Horner
2022-12-06 23:31:11 +00:00
parent bba9051b4b
commit 76031ee868
2 changed files with 21 additions and 11 deletions

View File

@@ -47,13 +47,13 @@ namespace ntfysh_client
SaveTopicsToFile(); SaveTopicsToFile();
} }
private void removeSelectedTopics_Click(object sender, EventArgs e) private async void removeSelectedTopics_Click(object sender, EventArgs e)
{ {
while (notificationTopics.SelectedIndex > -1) while (notificationTopics.SelectedIndex > -1)
{ {
string topicUniqueString = (string)notificationTopics.Items[notificationTopics.SelectedIndex]; string topicUniqueString = (string)notificationTopics.Items[notificationTopics.SelectedIndex];
_notificationListener.UnsubscribeFromTopic(topicUniqueString); await _notificationListener.UnsubscribeFromTopicAsync(topicUniqueString);
notificationTopics.Items.Remove(topicUniqueString); notificationTopics.Items.Remove(topicUniqueString);
} }

View File

@@ -37,8 +37,8 @@ namespace ntfysh_client
while (!cancellationToken.IsCancellationRequested) while (!cancellationToken.IsCancellationRequested)
{ {
using HttpResponseMessage response = await _httpClient.SendAsync(message, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); using HttpResponseMessage response = await _httpClient.SendAsync(message, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
await using Stream body = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); await using Stream body = await response.Content.ReadAsStreamAsync(cancellationToken);
try try
{ {
@@ -48,7 +48,7 @@ namespace ntfysh_client
{ {
//Read as much as possible //Read as much as possible
byte[] buffer = new byte[8192]; byte[] buffer = new byte[8192];
int readBytes = await body.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); int readBytes = await body.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
//Append it to our main buffer //Append it to our main buffer
mainBuffer.Append(Encoding.UTF8.GetString(buffer, 0, readBytes)); mainBuffer.Append(Encoding.UTF8.GetString(buffer, 0, readBytes));
@@ -125,25 +125,35 @@ namespace ntfysh_client
SubscribedTopicsByUnique.Add(unique, new SubscribedTopic(topicId, serverUrl, username, password, listenTask, listenCanceller)); SubscribedTopicsByUnique.Add(unique, new SubscribedTopic(topicId, serverUrl, username, password, listenTask, listenCanceller));
} }
public void UnsubscribeFromTopic(string topicUniqueString) public async Task UnsubscribeFromTopicAsync(string topicUniqueString)
{ {
if (_isDisposed) throw new ObjectDisposedException(nameof(NotificationListener)); if (_isDisposed) throw new ObjectDisposedException(nameof(NotificationListener));
#if DEBUG #if DEBUG
Debug.WriteLine($"Removing topic {topicUniqueString}"); Debug.WriteLine($"Removing topic {topicUniqueString}");
#endif #endif
// ReSharper disable once InlineOutVariableDeclaration - Needed to avoid nullable warning
SubscribedTopic topic;
//Topic isn't even subscribed, ignore //Topic isn't even subscribed, ignore
if (!SubscribedTopicsByUnique.TryGetValue(topicUniqueString, out SubscribedTopic? topic)) return; if (!SubscribedTopicsByUnique.TryGetValue(topicUniqueString, out topic!)) return;
//Cancel and dispose the task runner //Cancel and dispose the task runner
topic?.RunnerCanceller.Cancel(); topic.RunnerCanceller.Cancel();
//Wait for the task runner to shut down //Wait for the task runner to shut down
while (topic is not null && !topic.Runner.IsCompleted) Thread.Sleep(100); try
{
await topic.Runner;
}
catch (Exception)
{
// ignored
}
//Dispose task //Dispose task
topic?.Runner.Dispose(); topic.Runner.Dispose();
//Remove the old topic //Remove the old topic
SubscribedTopicsByUnique.Remove(topicUniqueString); SubscribedTopicsByUnique.Remove(topicUniqueString);