diff --git a/TwitchIrcClient/IRC/Badge.cs b/TwitchIrcClient/IRC/Badge.cs
index f5363b4..30c939c 100644
--- a/TwitchIrcClient/IRC/Badge.cs
+++ b/TwitchIrcClient/IRC/Badge.cs
@@ -9,6 +9,6 @@ namespace TwitchIrcClient.IRC
{
public record struct Badge(string Name, string Version)
{
-
+
}
}
diff --git a/TwitchIrcClient/IRC/Messages/UserNotice.cs b/TwitchIrcClient/IRC/Messages/UserNotice.cs
index e3a16b0..59c3406 100644
--- a/TwitchIrcClient/IRC/Messages/UserNotice.cs
+++ b/TwitchIrcClient/IRC/Messages/UserNotice.cs
@@ -85,9 +85,6 @@ namespace TwitchIrcClient.IRC.Messages
public string Id => TryGetTag("id");
public UserNoticeType? UserNoticeType => Enum.TryParse(TryGetTag("msg-id"), out UserNoticeType type)
? type : null;
- ///
- ///
- ///
public string Login => TryGetTag("login");
///
/// Whether the user is a moderator in this channel
@@ -263,21 +260,15 @@ namespace TwitchIrcClient.IRC.Messages
public UserType UserType
{ get
{
- if (!MessageTags.TryGetValue("user-type", out string? value))
- return UserType.None;
- switch (value.ToUpper())
+ var value = TryGetTag("user-type");
+ return value.ToUpper() switch
{
- case "ADMIN":
- return UserType.Admin;
- case "GLOBAL_MOD":
- return UserType.GlobalMod;
- case "STAFF":
- return UserType.Staff;
- case "":
- return UserType.Normal;
- default:
- throw new InvalidDataException();
- }
+ "ADMIN" => UserType.Admin,
+ "GLOBAL_MOD" => UserType.GlobalMod,
+ "STAFF" => UserType.Staff,
+ "" => UserType.Normal,
+ _ => UserType.Normal,
+ };
}
}
///
diff --git a/TwitchIrcClient/IRC/RateLimiter.cs b/TwitchIrcClient/IRC/RateLimiter.cs
index 3a93de7..071a8f1 100644
--- a/TwitchIrcClient/IRC/RateLimiter.cs
+++ b/TwitchIrcClient/IRC/RateLimiter.cs
@@ -88,25 +88,27 @@ namespace TwitchIrcClient.IRC
{
lock (Semaphore)
{
- Semaphore.Release(MessageLimit - Semaphore.CurrentCount);
+ var count = MessageLimit - Semaphore.CurrentCount;
+ if (count > 0)
+ Semaphore.Release(count);
}
}
- catch (SemaphoreFullException) { }
+ catch (SemaphoreFullException) { }
catch (ObjectDisposedException) { }
}
#region RateLimiter Dispose
- private bool disposedValue;
+ //https://stackoverflow.com/questions/8927878/what-is-the-correct-way-of-adding-thread-safety-to-an-idisposable-object
+ private int _disposedCount;
protected virtual void Dispose(bool disposing)
{
- if (!disposedValue)
+ if (Interlocked.Increment(ref _disposedCount) == 1)
{
if (disposing)
{
Semaphore?.Dispose();
Timer?.Dispose();
}
- disposedValue = true;
}
}
diff --git a/TwitchIrcClient/Program.cs b/TwitchIrcClient/Program.cs
index 885e0ed..e4ffc2f 100644
--- a/TwitchIrcClient/Program.cs
+++ b/TwitchIrcClient/Program.cs
@@ -52,7 +52,7 @@ async Task CreateConnection(string channel)
Console.Write("Channel: ");
var channelName = Console.ReadLine();
ArgumentNullException.ThrowIfNull(channelName, nameof(Channel));
-var connection = CreateConnection(channelName);
+var connection = await CreateConnection(channelName);
while (true)
{
//all the work happens in other threads