修改主线程C#上的变量

时间:2012-04-25 13:02:00

标签: c# wpf multithreading sockets

当套接字连接终止时,我正在数组中删除。我正在处理一个小聊天程序。我正在从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)。

帮助?

3 个答案:

答案 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>而不是自己管理计数器。