简体   繁体   中英

modify variable on main thread C#

I am doing a deletion in an array when a socket connection has been terminated.I am kindoff working on a little chat program.i am deleting an element from an array of User objects.

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; }
    }

}

the array is declared like this:

   User[] connected = new User[1024];  

and this is how i am deleting

            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

    }

The problem is that the counter for the user array is declared in the main wpf window.but i am executing the deletion method(Disconnection) in the threa associated to each socket.

Help?

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

In my opinion this entire method needs to be serialized because you are also changing the array of clients:

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

}

And please see if you can change the array to something more efficient! Not only do you have to manually keep track of the counter, but deleting from an array is an O(n) operation.

This isn't exactly answering your question directly, because I just have a few points to bring up.

First, why not use automatic properties? Instead of:

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

try

public Thread CLThread { get; set; }

You can do this for all of your properties.

Also, you're exposing the details of a disconnection externally. You should have a public Close() method in your User class that deals with closing sockets and aborting threads.

That said, aborting threads is evil. You should use an approach like having the thread return gracefully when an event gets signaled, and then call the thread's Join() method in Close() to wait for the thread to exit.

I agree with Reniuz -- use a List<User> instead and avoid managing the counter yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM