C
C#10mo ago
Draethius

❔ Code only firing when using breakpoints in Visual Studio

I am having an issue with my code for a Twitch bot(Using TwitchLIB API) Certain lines of code will work just fine, but others will only work when using a breakpoint inside of their methods, and i'm unsure why this is working this way. The point of breakpoints is so that I can see what lines of my code are being fired, and where issues are, but how am I supposed to troubleshoot if the code works when I use the breakpoints? I've used a logging method to verify, and the code is REACHED just fine without the breakpoints. Any ideas? I'll include some of my code in a reply to this thread.
20 Replies
Draethius
Draethius10mo ago
I have a line of code that fired when the bot joins a twitch channel, that sends perfectly fine. Nothing is setup differently that I can see(code below sends the message just fine)
private void Client_OnJoinedChannel(object sender, OnJoinedChannelArgs e)
{
// Channel variables
String ChannelName = e.Channel;

client.SendMessage(ChannelName, "LionizedBot has joined the channel!"); // joined channel message
form1.twitchLog($"{e.BotUsername} has joined {ChannelName}'s channel!");
etc etc }
private void Client_OnJoinedChannel(object sender, OnJoinedChannelArgs e)
{
// Channel variables
String ChannelName = e.Channel;

client.SendMessage(ChannelName, "LionizedBot has joined the channel!"); // joined channel message
form1.twitchLog($"{e.BotUsername} has joined {ChannelName}'s channel!");
etc etc }
But then for my command and welcome message functionality, the client.SendMessage only actually sends a message when I am using breakpoints inside of the method that they are in. Below is my logic for welcome messages
private void Client_OnMessageReceived(object sender, OnMessageReceivedArgs e)
{
// Message variables
String messageSender = e.ChatMessage.DisplayName.ToLower();
String channel = e.ChatMessage.Channel.ToLower();

form1.twitchLog($"{messageSender} sent a message in {channel}'s stream!");

// Sends intro message
if (introMessageDict[channel].ContainsKey(messageSender))
{
if (introMessageDict[channel][messageSender] == true)
{
if (messageSender == "XXX" || messageSender == "XXX")
{
client.SendMessage(channel, $"𝙇𝙞𝙤𝙣 𝙂𝙖𝙣𝙜! 𝙎𝙝𝙤𝙬 {messageSender} 𝙨𝙤𝙢𝙚 𝙡𝙤𝙫𝙚! https://www.youtube.com/{messageSender}");
introMessageDict[channel][messageSender] = false;
}
else if (messageSender == "XXX")
{
client.SendMessage(channel, $"𝙇𝙞𝙤𝙣 𝙂𝙖𝙣𝙜! 𝙎𝙝𝙤𝙬 {messageSender} 𝙨𝙤𝙢𝙚 𝙡𝙤𝙫𝙚! https://www.youtube.com/@XXX");
introMessageDict[channel][messageSender] = false;
}
else
{
client.SendMessage(channel, $"𝙇𝙞𝙤𝙣 𝙂𝙖𝙣𝙜! 𝙎𝙝𝙤𝙬 {messageSender} 𝙨𝙤𝙢𝙚 𝙡𝙤𝙫𝙚! https://www.twitch.tv/{messageSender}");
introMessageDict[channel][messageSender] = false;
}

}
}

}
private void Client_OnMessageReceived(object sender, OnMessageReceivedArgs e)
{
// Message variables
String messageSender = e.ChatMessage.DisplayName.ToLower();
String channel = e.ChatMessage.Channel.ToLower();

form1.twitchLog($"{messageSender} sent a message in {channel}'s stream!");

// Sends intro message
if (introMessageDict[channel].ContainsKey(messageSender))
{
if (introMessageDict[channel][messageSender] == true)
{
if (messageSender == "XXX" || messageSender == "XXX")
{
client.SendMessage(channel, $"𝙇𝙞𝙤𝙣 𝙂𝙖𝙣𝙜! 𝙎𝙝𝙤𝙬 {messageSender} 𝙨𝙤𝙢𝙚 𝙡𝙤𝙫𝙚! https://www.youtube.com/{messageSender}");
introMessageDict[channel][messageSender] = false;
}
else if (messageSender == "XXX")
{
client.SendMessage(channel, $"𝙇𝙞𝙤𝙣 𝙂𝙖𝙣𝙜! 𝙎𝙝𝙤𝙬 {messageSender} 𝙨𝙤𝙢𝙚 𝙡𝙤𝙫𝙚! https://www.youtube.com/@XXX");
introMessageDict[channel][messageSender] = false;
}
else
{
client.SendMessage(channel, $"𝙇𝙞𝙤𝙣 𝙂𝙖𝙣𝙜! 𝙎𝙝𝙤𝙬 {messageSender} 𝙨𝙤𝙢𝙚 𝙡𝙤𝙫𝙚! https://www.twitch.tv/{messageSender}");
introMessageDict[channel][messageSender] = false;
}

}
}

}
form1.TwitchLog is my logging functionality into a textbox on my form, and client is a public TwitchClient variable that is initialized in the below method when I click a button
public void InitializeClient(String username, String accessToken)
{
// Twitch Client variables
client = new TwitchClient();
client.Initialize(new ConnectionCredentials(username, accessToken), TwitchChannelName);

// Events you want to subscribe to
client.OnConnected += Client_OnConnection;
client.OnDisconnected += Client_OnDisconnected;
client.OnJoinedChannel += Client_OnJoinedChannel;
client.OnChatCommandReceived += Client_OnCommandReceived;
client.OnMessageReceived += Client_OnMessageReceived;
client.Connect();

}
public void InitializeClient(String username, String accessToken)
{
// Twitch Client variables
client = new TwitchClient();
client.Initialize(new ConnectionCredentials(username, accessToken), TwitchChannelName);

// Events you want to subscribe to
client.OnConnected += Client_OnConnection;
client.OnDisconnected += Client_OnDisconnected;
client.OnJoinedChannel += Client_OnJoinedChannel;
client.OnChatCommandReceived += Client_OnCommandReceived;
client.OnMessageReceived += Client_OnMessageReceived;
client.Connect();

}
Angius
Angius10mo ago
Generally, if some code works in debug but not otherwise, it's because something async doesn't get awaited
Draethius
Draethius10mo ago
Hmm I only have two methods that are async, and they are both awaited(neither of them are the affected methods). I'm assuming something within the API could be asynced and need awaited?
Angius
Angius10mo ago
Possibly Since debugging slows down the code, some of the asynchronous code has the time to resolve properly, even without await. That's why it's my first suspicion
Draethius
Draethius10mo ago
But that also confuses me as to why it would work in one(OnJoinedChannel) but not the other (OnChatCommandReceived or OnMessageReceived)
Angius
Angius10mo ago
Often happens when async void methods exist
Draethius
Draethius10mo ago
Both of my asyncs are tasks, I do have an async void method lower in the list, but it only gets called when I press a different button.
Angius
Angius10mo ago
Huh, yeah, async void is unavoidable in GUI apps because event handlers cannot be asynchronous Depending on the framework, there are various ways to deal with that, though
Draethius
Draethius10mo ago
Yeah so I have async void in my form for all the button clicks and closing the form, and then I have an async void method for when my eventsub connects(it awaits a list of all users from a list I made)
private async void Es_Websocketconnected(object? sender, WebsocketConnectedArgs e)
{
var newApi = new TwitchAPI(settings: new ApiSettings()
{
ClientId = ClientId,
AccessToken = clientAccessToken,
});
var user = await api.Helix.Users.GetUsersAsync(null, lMembers, clientAccessToken);
private async void Es_Websocketconnected(object? sender, WebsocketConnectedArgs e)
{
var newApi = new TwitchAPI(settings: new ApiSettings()
{
ClientId = ClientId,
AccessToken = clientAccessToken,
});
var user = await api.Helix.Users.GetUsersAsync(null, lMembers, clientAccessToken);
But this isn't called until I press my second button so that shouldn't affect everything above.
333fred
333fred10mo ago
The other possibility with debug mode, besides Z's points, is that maybe when you stop on a breakpoint, VS evaluates some property that causes a side effect, and your program is effectively depending on those side effects In order to show the locals window, VS needs to evaluate properties and such to get their values
Draethius
Draethius10mo ago
Hmm i'm not sure I follow
333fred
333fred10mo ago
Your code has properties in it, yes?
Draethius
Draethius10mo ago
Yeah ofc
Angius
Angius10mo ago
Any that are not autoproperties? That is, more than just { get; set; }?
Draethius
Draethius10mo ago
I don't believe so no I do have this class inside of a class, but I don't think that's what you mean
// Commands class stores values for the command
public class command
{
public String cmd;
public String cmdText;
public bool hasTimer;
public int timerLength;

public command(string cmd, string cmdText, bool hasTimer)
{
this.cmd = cmd;
this.cmdText = cmdText;
this.hasTimer = hasTimer;
this.timerLength = 0;
}

}
// Commands class stores values for the command
public class command
{
public String cmd;
public String cmdText;
public bool hasTimer;
public int timerLength;

public command(string cmd, string cmdText, bool hasTimer)
{
this.cmd = cmd;
this.cmdText = cmdText;
this.hasTimer = hasTimer;
this.timerLength = 0;
}

}
Angius
Angius10mo ago
No, that's fine Well, some questionable choices, but mostly stylistic, and nothing that'd cause the sort of issue you describe
Draethius
Draethius10mo ago
Here are the variables I have set in this class, + 2 arrays and 2 dictionaries, but nothing else that looks to be out of the ordinary
Accord
Accord10mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Draethius
Draethius10mo ago
This has not been resolved yet, unsure what is going on
Accord
Accord10mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.