当套接字连接终止时,我正在数组中删除。我正在处理一个小聊天程序。我正在从User对象数组中删除一个元素。
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中执行删除方法(Disconnection)。
帮助?
答案 0 :(得分:2)
在用户数组的计数器周围使用锁定,因为您正在从多个线程中减少它。
答案 1 :(得分:1)
在我看来,整个方法需要序列化,因为你也在改变客户端数组:
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)操作。
答案 2 :(得分:0)
这并不是直接回答你的问题,因为我只想提出几点意见。
首先,为什么不使用自动属性?而不是:
public Thread CLThread
{
get { return clthread; }
set { clthread = value; }
}
试
public Thread CLThread { get; set; }
您可以为所有属性执行此操作。
此外,您还在外部公开断开连接的详细信息。您应该在Close()
类中使用公共User
方法来处理关闭套接字和中止线程。
那就是说,中止线程是邪恶的。您应该使用一种方法,例如在事件发出信号时让线程正常返回,然后在Join()
中调用线程的Close()
方法以等待线程退出。
我同意Reniuz - 使用List<User>
而不是自己管理计数器。