How to Manipulate Objects in a Thread?

Asked

Viewed 304 times

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 shows an image on the screen, and these images keep moving on the screen.

Ex: if the user sets the variable QtdUsuario for 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 to: How can I identify possible collisions between these objects (images)? And how can I define individual values for each object ? Ex: user will say that image 1 will have idade = 5, and decreases and increases that one idade ?

2 answers

2


Right now your threads don’t have enough information. This is because threads need to know the state of the objects in the remaining threads (i.e., they need to share state).

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

Let me give you an example, but without any guarantees 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;
        }
    }
}
  • Perhaps it would be better to have only one thread. As you can see most of the code has synchronization and so will not take advantage of the parallelism

1

The delegate ParameterizedThreadStart has the following signature:

public delegate void ParameterizedThreadStart(object obj);

This indicates that your method Metodo should follow it, receiving the state as a object.

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

Another way to do it would be to directly pass a lambda as argument in the creation of Thread:

th = new Thread(() => Metodo(obj));

Browser other questions tagged

You are not signed in. Login or sign up in order to post.