c#交叉线程.IRC流线程到主UI线程

本文关键字:线程 UI IRC | 更新日期: 2023-09-27 18:13:36

我一直在尝试让这个小IRC程序工作,但由于某种原因,我有VS和交叉线程的问题。我不确定是我做得不对还是怎么的。以下是导致问题的部分。

主线程:

public partial class MainUI : Form 
{
    private static IRC irc = new IRC();
    public MainUI()
    {
        InitializeComponent();
    }
    public static void StartIRC()
    {
        irc.Start();
    }
}

IRC线程:

class IRC 
{
    private Thread ircThread;
    private bool _running  = true;
    private NetworkStream stream;
    private StreamWriter writer;
    private StreamReader reader;
    private TcpClient irc;
    public IRC(){
        ircThread = new Thread(new ThreadStart(Run));
        ircThread.IsBackground = true;
    }
    public void Run(){
        while (_running) {
            parseInStream(reader.ReadLine());
        }
    }
    public void Start()
    {
        ircThread.Start();
    }
    private void parseInStream(String inText)
    {
        String[] text = inText.Split(' ');
        String name;
        String message;
        if (text[1].Equals("PRIVMSG")) {
            name = capsFirstChar(getUser(inText));
            message = inText.Substring(inText.IndexOf(":", 1) + 1);
            sendToChatBox(capsFirstChar(name) + ": " + message, Color.Black);
        }
        else if (text[1].Equals("JOIN")) {
            name = getUser(inText);
            sendToChatBox(capsFirstChar(name) + " has joined the channel.", Color.LimeGreen);
        }
        else if (text[1].Equals("PART")) {
            name = getUser(inText);
            sendToChatBox(capsFirstChar(name) + " has left the channel.", Color.Red);
        }
    }
    public void sendToChatBox(String text, Color color)
    {       
        //Trying to send the text to the chatbox on the MainUI
        //Works if the MainUI.Designer.cs file has it set to static
        if (MainUI.txtMainChat.InvokeRequired) {
            MainUI.txtMainChat.Invoke((MethodInvoker)delegate() {
                sendToChatBox(text, color);
            });
        }
        else {
            MainUI.txtMainChat.SelectionColor = color;
            MainUI.txtMainChat.AppendText(text);
        }
    }
    private String getUser(String msg)
    {
        String[] split = msg.Split('!');
        user = split[0].Substring(1);
        return capsFirstChar(user);
    }
    private String capsFirstChar(String text)
    {
        return char.ToUpper(text[0]) + text.Substring(1).ToLower();
    }
}

我能够让它工作的唯一方法是,如果我进入MainUI.Designer.cs文件并将文本框更改为静态,然后从这里更改一切。txtMainChatto MainUI.txtMainChat .

我的主要问题是,当我在视觉方面做任何改变时,所有标记为静态或命名为MainUI的东西都被删除了。我在想我该怎么做才能不让这事发生。我这样做对吗,还是有更好的方法?我尝试使用后台工作器,但由于某种原因,它使用了大量的处理能力。

我在网上找了一遍,似乎找不到一个与我的设置有什么关系。我看到有人从主线程调用一个线程,然后从主线程向被调用的线程发送东西,但不是相反。没有其他东西被写入到文本框中,所以不会有两个线程同时使用它的问题。

c#交叉线程.IRC流线程到主UI线程

在我的主UI线程中,我传入了"this",这样我就可以从IRC类中引用主窗口。MainUI.txtMainChat

irc = new IRC(this);

然后在我的IRC类

MainUI main;
public IRC(MainUI main){
    this.main = main;
    ircThread = new Thread(new ThreadStart(Run));
    ircThread.IsBackground = true;
}

然后我可以改变

//MainUI.txtMainChat to
main.txtMainChat

就像Cameron说的,虽然我知道我被告知这不是最好的方法,但它能让我开始。

每次在设计器中更改UI时,都会重新构建设计器文件。

你需要把MainUi传递给你的IRC类,或者给它一个抽象的接口(最好的选择)。

public interface IMainUI
{
    void AddText(string text, Color color);
    void UiThread(Action code);
}
public class MainUI : IMainUI
{
     // Whatever else
    public void AddText(string text, Color color)
    {
        UiThread( () => 
        {
           // Same code that was in your Irc.SendToChatBox method.     
        });
    }
    public void UiThread(Action code)
    {
        if (InvokeRequired)
        {
            BeginInvoke(code);
            return;
        }
        code.Invoke();
    }
}
public class IRC
{
    IMainUI _mainUi;
    //Other properties, and fields    
    public IRC(IMainUI mainUi)
    {
        this._mainUi = mainUi;
        // Other constructor stuff.
    }
    // Other logic and methods
}