I have looked for a solution for my problem, but I couldn't find it yet.
I'm coding a bot which will be connected to an irc server. I want the user to have access to a win forms window where it is possible to input the server, channel, and so on.
This is the window:
I have set the console output to update my textbox with the code in the main program. With this, I get all text coming from the child classes into my text box.
static class Program
{
private static Form1 Form1;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
using (var consoleWriter = new ConsoleWriter())
{
consoleWriter.WriteLineEvent += consoleWriter_WriteLineEvent;
Console.SetOut(consoleWriter);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 = new Form1();
Application.Run(Form1);
}
}
static void consoleWriter_WriteLineEvent(object sender, ConsoleWriterEventArgs msg)
{
var message = msg.Value;
Form1.statusTextBox.AppendText(message + "\r\n");
}
}
public class ConsoleWriter : TextWriter
{
public override Encoding Encoding { get { return Encoding.UTF8; } }
public override void Write(string value)
{
if (WriteEvent != null) WriteEvent(this, new ConsoleWriterEventArgs(value));
base.Write(value);
}
public override void WriteLine(string value)
{
if (WriteLineEvent != null) WriteLineEvent(this, new ConsoleWriterEventArgs(value));
base.WriteLine(value);
}
public event EventHandler<ConsoleWriterEventArgs> WriteEvent;
public event EventHandler<ConsoleWriterEventArgs> WriteLineEvent;
}
public class ConsoleWriterEventArgs : EventArgs
{
public string Value { get; private set; }
public ConsoleWriterEventArgs(string value)
{
Value = value;
}
}
Now I call this in my Form1, when the button "Connect" is clicked on:
gbaIrcBot.Connect(server, null, port, nick, channelList);
Inside the gbaIrcBot.Connect(), i have among other things:
private void ReadStream()
{
string inputLine;
while ((inputLine = _streamReader.ReadLine()) != null)
{
var splitInput = inputLine.Split(new[] { ' ' });
if (splitInput.ElementAt(0) == "PING") { Pong(splitInput.ElementAt(1)); continue;}
switch (splitInput.ElementAt(1))
{
case "001": foreach (var channel in ChannelList) JoinChannel(channel); break;
case "PRIVMSG": ProcessPrivMsg(splitInput); break;
case "433": SetNick("AlternativeBOT"); break;
default: Console.WriteLine(inputLine); break;
}
}
}
This method is responsible for reading all inputs from the irc server. When I get messages from the server, I send it to the console, which updates the textbox in Form1. It MUST be an infinite loop.
All this works well if I dont create a thread to keep my UI not frozen. This is an example:
When I try to create a thread, My Form1 throws an exception saying its a cross-thread message, and I cannot update it from outside.
Any idea to solve it?