How to manipulate objects in a Thread?

2

I have the following code:

MinhaClasse[] obj = new MinhaClasse[QtdUsuario];
Thread th;

For(int i = 0; i < QtdUsuario; i++)
{
    obj[i] = new MinhaClasse();

    th = new Thread(new ParameterizedThreadStart(Metodo));
    th.SetApartmentState(ApartmentState.STA);
    th.IsBackground = true;
    th.Start(obj[i]);
}

Each object displays an image on the screen, and these images move around the screen.

Ex: If the user sets the variable QtdUsuario to 5 I will have 5 objects and each object in a thread. Then on the screen I will have 5 images moving randomly.

My goal is: How can I identify possible collisions between these objects (images)? And how can I define individual values for each object? Ex: the user will say that image 1 will have idade = 5, and decrements e or increases this idade ?

    
asked by anonymous 28.11.2016 / 23:25

2 answers

2

At this moment your threads do not have enough information. This is because threads need to know the state of the objects in the remaining threads (ie they need to share state).

It may not be obvious, but the state you have to share is the array and it does not need to be synchronized . Already the access to each element of the array needs, when it queries the objects of the other threads.

I'll give you an example, but without any assurances that might be useful in your scenario:

public class Imagem{
    public Point Posicao{get; set;}

    public int Idade{get; set;}
}

public class Estado{
    public Imagem[] Imagens{get; set;}

    public Imagem MinhaImagem{get; set;}
}

var imagens = new Imagem[QtdUsuario];
//vamos assegurar que o array é inicializado antes de o passar como estado as threads
for(var i = 0; i < QtdUsuario; ++i){
    imagens[i] = new Imagem();
}

for(var i = 0; i < QtdUsuario; ++i){
    var thread = new Thread(new ParameterizedThreadStart(Metodo));
    thread.SetApartmentState(ApartmentState.STA);
    thread.IsBackground = true;
    thread.Start(new Estado(){Imagens = imagens, MinhaImagem = imagens[i]});
}

private void Metodo(object parametro)
{
    Estado estado = parametro as Estado;

    //o lock está a ser feito perante o array
    //porque é necessário fazer lock por um objeto comum
    lock(estado.Imagens){
        //Verifica qual o estado das restantes imagens
        var algumaImagemNaPosicao = estado.Imagens
           .Any(img => img != estado.MinhaImagem && 
                img.Posicao.X == 10 && img.Posicao.Y == 2);

        if(!algumaImagemNaPosicao){
            //faz coisas com a imagem
            estado.MinhaImagem.Posicao.X = 10;
            estado.MinhaImagem.Posicao.y = 2;
        }
    }
}
    
29.11.2016 / 13:25
1

Delegate ParameterizedThreadStart has the following signature:

public delegate void ParameterizedThreadStart(object obj);

This indicates that your Metodo method should follow it, getting the status as a object .

private void Metodo(object parametro)
{
   // Neste ponto já estamos em outra thread
   var paramMinhaClasse = (MinhaClasse) parametro;
}

Another way to do this would be to directly pass a lambda as an argument to the Thread creation:

th = new Thread(() => Metodo(obj));
    
28.11.2016 / 23:42