修改主线程 C# 上的变量

本文关键字:变量 线程 修改 | 更新日期: 2023-09-27 18:32:07

当套接字连接终止时,我正在数组中进行删除。我正在开发一个小聊天程序。我正在从用户对象数组中删除一个元素。

public class User
{
    private Thread clthread;
    private string name;
    private Socket sock;
    public User(string _name, Thread _thread, Socket _sock)
    {
        sock = socket();
        clthread = _thread;
        name = _name;
        sock = _sock;
    }
    private Socket socket()
    {
        return new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    }//initiaza socket nou
    public Thread CLThread
    {
        get { return clthread; }
        set { clthread = value; }
    }
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    public Socket Sock
    {
        get { return sock; }
        set { sock = value; }
    }
}

数组声明如下:

   User[] connected = new User[1024];  

这就是我删除的方式

            private void Disconnection(int id)
    {
        User client = connected[id];
        for (int i = id; i < no - 1; i++)
        {
            connected[i] = connected[i + 1];
        }
        client.Sock.Close();
        client.CLThread.Abort();

        no--;
        MessageBox.Show(no.ToString());
        //ui clean
    }

问题是用户数组的计数器是在主 wpf 窗口中声明的,但我正在与每个套接字关联的 threa 中执行删除方法(断开连接)。

帮助?

修改主线程 C# 上的变量

使用用户数组计数器周围的锁,因为您要从多个线程递减它。

在我看来,整个方法需要序列化,因为您也在更改客户端数组:

object locker = new object(); // globally visible lock
...
private void Disconnection(int id)
{        
    lock(locker)
    {
        User client = connected[id];
        for (int i = id; i < no - 1; i++)
        {
            connected[i] = connected[i + 1];
        }
        client.Sock.Close();
        client.CLThread.Abort();
        no--;      
        MessageBox.Show(no.ToString());
    }
    //ui clean
}

看看是否可以将数组更改为更高效的数组!您不仅必须手动跟踪计数器,而且从数组中删除是一个 O(n) 操作。

这并不完全直接回答你的问题,因为我只有几点要提出。

首先,为什么不使用自动属性? 而不是:

public Thread CLThread
{
    get { return clthread; }
    set { clthread = value; }
}

尝试

public Thread CLThread { get; set; }

您可以对所有媒体资源执行此操作。

此外,您还会在外部公开断开连接的详细信息。 在 User 类中应该有一个公共 Close() 方法,用于关闭套接字和中止线程。

也就是说,中止线程是邪恶的。 您应该使用一种方法,例如在事件收到信号时让线程优雅地返回,然后在 Close() 中调用线程的 Join() 方法来等待线程退出。

我同意 Reniuz 的观点——改用List<User>,避免自己管理柜台。