2014-02-26 23 views
0

我已经为我的问题寻找解决方案,但是我找不到它。使用线程无法工作,但如果代码在win窗体中工作

我正在编写一个将连接到irc服务器的bot。我希望用户能够访问可以输入服务器,频道等的获胜窗体窗口。

这是窗口:

enter image description here

我已经设置了控制台输出来更新我的主程序代码文本框。有了这个,我将所有来自子类的文本都放到我的文本框中。

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中的文本框。它必须是一个无限循环。

所有这一切运作良好,如果我不创建一个线程,以保持我的用户界面不被冻结。这是一个例子:

enter image description here

当我尝试创建一个线程,我Form1中抛出一个异常,并称其跨线程消息,我不能从外部进行更新。

任何想法解决它?

+0

如果您使用的后台工作,你应该能够使用OnProgressChanged事件更新UI。如果您需要更改正在运行的线程中的设置,则可以取消该线程并使用更新后的设置启动一个新线程。 – jle

回答

0

表格上的更新必须在窗口中更新线程来完成。

您可以通过使用BeginInvoke()包装您的呼叫来强制执行此类线程。

变化

Form1.statusTextBox.AppendText(message + "\r\n"); 

Form1.BeginInvoke(() => Form1.statusTextBox.AppendText(message + "\r\n")); 
相关问题