Search code examples
c#wpfirc

WPF-App unsuable when using IRC-Client in Twitch [C#]


I want to set up my own TwitchBot with a nice User-Interface. But I ran into some troubles: I am sorry about the formatting, but it doesn't copy it from Visual Studio nicely and formatting here seems horrible.

public class IrcClient
{
        private string userName;
        private string channel;

        private TcpClient tcpClient;
        private StreamReader inputStream;
        private StreamWriter outputStream;

        public IrcClient(string ip, int port, string userName, string password, string channel)
        {
            this.userName = userName;
            this.channel = channel;

            tcpClient = new TcpClient(ip, port);
            inputStream = new StreamReader(tcpClient.GetStream());
            outputStream = new StreamWriter(tcpClient.GetStream());

            outputStream.WriteLine($"PASS {password}");
            outputStream.WriteLine($"NICK {userName}");
            outputStream.WriteLine($"USER {userName} 8 * :{userName}");
            outputStream.WriteLine($"JOIN #{channel}");
            outputStream.Flush();
        }

        public string ReadMessage()
        {
            return inputStream.ReadLine();
        }
}

This is my class in which I set up the IRC-Client. Then I use the standard WPF/C# build in Visual Studio with


        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            
            System.Windows.Threading.DispatcherTimer dispatcherTimerChat = new System.Windows.Threading.DispatcherTimer();

            dispatcherTimerChat.Tick += new EventHandler(dispatcherTimerChat_tick);
            dispatcherTimerChat.Interval = new TimeSpan(500000);

            dispatcherTimerChat.Start();

            client = new IrcClient("irc.twitch.tv", 6667, "x", "x", "x");

            var pinger = new Pinger(client);
            pinger.Start();

        }

        private void dispatcherTimerChat_tick(object sender, EventArgs e)
        {
            Console.WirteLine(client.ReadMessage());
        }

Window_loaded gets called when the main window is loaded. In there I simply want to receive what's being written in the chat. But the UI lags horribly. When I put some basic stuff into the XAML code, like Richttextbox, I cannot even write in there without a solid delay. While lowering the TimeSpan(x) helps, but reading the chat in a reasonably populated channel then is problematic. Something goes wrong here obviously but I don't know what.

The Pinger Class just pings every 5 minutes so I don't get kicked from the channel and runs on its own thread.

This is not the full code but only the bare minimum to get a WPF form running is missing.


Solution

  • Thanks to the comment from aepot I looked into async programming. This solution worked for me:

    I added a function

    private async Task<string> getChat()
    {
        string msg = await Task.Run(() => client.ReadMessage());
    
        return msg;
    }
    

    and changed the dispatcher function to

    private async void dispatcherTimerChat_tick(object sender, EventArgs e)
    {
        string msg = await getChat();
    
        Console.WriteLine(msg);
    }
    

    This tutorial helped me along the way.