我已经为我的问题寻找解决方案,但是我找不到它。使用线程无法工作,但如果代码在win窗体中工作
我正在编写一个将连接到irc服务器的bot。我希望用户能够访问可以输入服务器,频道等的获胜窗体窗口。
这是窗口:
我已经设置了控制台输出来更新我的主程序代码文本框。有了这个,我将所有来自子类的文本都放到我的文本框中。
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;
}
}
现在我把这个在我的Form1上,点击按钮 “连接” 上时:
gbaIrcBot.Connect(server, null, port, nick, channelList);
的gbaIrcBot.Connect()里面,我有其中包括:
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;
}
}
}
该方法负责读取来自irc服务器的所有输入。当我从服务器获取消息时,我将它发送到控制台,该控制台更新Form1中的文本框。它必须是一个无限循环。
所有这一切运作良好,如果我不创建一个线程,以保持我的用户界面不被冻结。这是一个例子:
当我尝试创建一个线程,我Form1中抛出一个异常,并称其跨线程消息,我不能从外部进行更新。
任何想法解决它?
如果您使用的后台工作,你应该能够使用OnProgressChanged事件更新UI。如果您需要更改正在运行的线程中的设置,则可以取消该线程并使用更新后的设置启动一个新线程。 – jle