c# - 使用 Invoke 时跨线程操作无效

标签 c# sockets invoke required

我做了一个聊天系统,但遇到了这个错误:

Cross-thread operation not valid: 'MessageBox' etc.

我所做的:我添加了一个调用。这是代码:

Invoke(new Action(() => messageBox.Items.Add(usersName.Text + ": " + receivedMessage)));

问题是,它基本上从其他用户发送了一条空白消息。这是因为我在本地连接到聊天。这是一张图片:

Chat Application

接收消息:

private void MessageCallBack(IAsyncResult aResult)
{
    try
    {
        byte[] receivedData = new byte[1500];
        receivedData = (byte[])aResult.AsyncState;
        ASCIIEncoding aEncoding = new ASCIIEncoding();
        string receivedMessage = aEncoding.GetString(receivedData);
        Invoke(new Action(() => messageBox.Items.Add(usersName.Text + ": " + receivedMessage)));
        buffer = new byte[1500];
        socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref theirIp, new AsyncCallback(MessageCallBack), buffer);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

发送消息:

private void sendBtn_Click(object sender, EventArgs e)
{
    try
    {
        if (messageTb.Text == "")
        {
            return;
        }
        else
        {
            ASCIIEncoding eEncoding = new ASCIIEncoding();
            byte[] msg = new byte[1500];
            msg = eEncoding.GetBytes(messageTb.Text);
            socket.Send(msg);
            messageBox.Items.Add(yourName.Text + ": " + messageTb.Text);
            messageTb.Clear();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    this.ActiveControl = messageTb;
}

最佳答案

每当您尝试访问表单主线程之外的不同线程中的控件时,就会发生此异常。

我使用下面的简单日志机制,这只适合简单的应用程序。

private delegate void LogDelegate(ListBox messageBox, string data);

private LogDelegate _logDelegate;
private void Log(ListBox messageBox, string data)
{
    if (messageBox.InvokeRequired)
    {
        LogDelegate logDelegate = Log;
        Invoke(logDelegate, messageBox, data);
    }
    else
    {
        messageBox.Items.Add(data);
    }
}

public Form1()
{
    InitializeComponent();
    //don't forget, initialize the delegate
    _logDelegate = Log;
}

private void btn_Start_Click(object sender, EventArgs e)
{
    Log("Anything to log");
}
private void MessageCallBack(IAsyncResult aResult)
{
    try
    {
        //Instead of Invoke use 
        //Invoke(new Action(() => messageBox.Items.Add(usersName.Text + ": " + receivedMessage)));
        Log("Anything to log");

    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

正如我所说,该代码可以在任何地方使用并且很简单。但为了更复杂的日志机制和更好的性能,请使用 Log4Net 或 NLog。

关于c# - 使用 Invoke 时跨线程操作无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35230729/

相关文章:

linux - Linux 中的 TIPC 套接字类型

c - IPv6 的 getaddrinfo() 没有意义

polymorphism - 在 D 中非多态调用实例方法?

c# - 后台工作人员委托(delegate)和调用者

JavaFX : invoking ' Application.launch(args) ' from a method other than main

c# - 如何使用 Windows 窗体数据网格更新数据库? ( Visual Studio 2010)

c# - 适用于小型企业应用程序的后端或数据库系统

c++ - 从 tcp 迁移到 udp 时,‘acceptor’ 不是 ‘boost::asio::ip::udp’ 的成员

c# - 我的 XUnit dotnet 核心项目在我的桌面上构建,但不在 DevOps Server 2019 中构建

c# - 如何设置 Windows 服务的权限