2009-09-01 69 views
25

Cómo compartir datos entre diferentes hilos En C# sin usar las variables estáticas? ¿Podemos crear un machanism utilizando el atributo?Cómo compartir datos entre diferentes hilos En C# usando AOP?

¿Ayudará la programación orientada a aspectos en tales casos?

Para lograr esto, todos los diferentes hilos deberían funcionar en un solo objeto?

+2

Puede acceder a cualquier variable en el alcance de un hilo. p.ej. 2 hilos pueden llamar a la misma función y acceder a la instancia miembro/variables estáticas. Compartir es trivial, sincronizar el acceso variable a través de múltiples hilos es la tarea más diff. – Gishu

+1

Estamos tratando de leer la instancia de objeto disponible en un hilo en otro hilo, y tenemos una restricción para mantener variable global/estática, ¿hay alguna buena idea para lograrlo? –

+0

No tiene acceso a los hilos como tal. Más bien, accedes a objetos que los hilos pueden ver. Si el código que se ejecuta en un subproceso puede acceder a una instancia de objeto, o datos estáticos, puede cambiarlo. Si otro hilo puede ver esa instancia o datos estáticos, entonces se ha comunicado entre los dos hilos. – djna

Respuesta

5

Puede pasar un objeto como argumento al Thread.Start y utilizarlo como un almacenamiento de datos compartido entre el subproceso actual y el subproceso iniciador.

También puede simplemente acceder directamente (con el bloqueo correspondiente del curso) a sus miembros de datos, si comenzó la cadena utilizando el formulario de instancia del delegado ThreadStart.

No puede usar atributos para crear datos compartidos entre hilos. Puede usar las instancias de atributos adjuntas a su clase como almacenamiento de datos, pero no veo cómo es mejor que usar miembros de datos estáticos o de instancia.

+2

Para usar como almacenamiento compartido de datos, ¿necesita buscar alguna variable estática/global? –

+0

El código que inició el hilo obviamente tiene una referencia al objeto pasado como parámetro al Thread.Start. El procedimiento de subproceso también tiene una referencia a ese objeto. Por lo tanto, pero las piezas de código pueden escribir en él sin que ese objeto tenga que ser una variable estática. –

+2

sí ... lo tengo ...Por favor, escriba algún fragmento de código para una mejor comprensión –

16

No se puede superar la simplicidad de una cola de mensajes bloqueada. Yo digo que no pierdas tu tiempo con algo más complejo.

Lea en la instrucción de bloqueo.

lock

EDITAR

Aquí se muestra un ejemplo del objeto de Microsoft cola envuelta por lo que todas las acciones en contra son seguros para subprocesos.

public class Queue<T> 
{ 
    /// <summary>Used as a lock target to ensure thread safety.</summary> 
    private readonly Locker _Locker = new Locker(); 

    private readonly System.Collections.Generic.Queue<T> _Queue = new System.Collections.Generic.Queue<T>(); 

    /// <summary></summary> 
    public void Enqueue(T item) 
    { 
     lock (_Locker) 
     { 
      _Queue.Enqueue(item); 
     } 
    } 

    /// <summary>Enqueues a collection of items into this queue.</summary> 
    public virtual void EnqueueRange(IEnumerable<T> items) 
    { 
     lock (_Locker) 
     { 
      if (items == null) 
      { 
       return; 
      } 

      foreach (T item in items) 
      { 
       _Queue.Enqueue(item); 
      } 
     } 
    } 

    /// <summary></summary> 
    public T Dequeue() 
    { 
     lock (_Locker) 
     { 
      return _Queue.Dequeue(); 
     } 
    } 

    /// <summary></summary> 
    public void Clear() 
    { 
     lock (_Locker) 
     { 
      _Queue.Clear(); 
     } 
    } 

    /// <summary></summary> 
    public Int32 Count 
    { 
     get 
     { 
      lock (_Locker) 
      { 
       return _Queue.Count; 
      } 
     } 
    } 

    /// <summary></summary> 
    public Boolean TryDequeue(out T item) 
    { 
     lock (_Locker) 
     { 
      if (_Queue.Count > 0) 
      { 
       item = _Queue.Dequeue(); 
       return true; 
      } 
      else 
      { 
       item = default(T); 
       return false; 
      } 
     } 
    } 
} 

EDITAR 2

espero que este ejemplo ayuda. Recuerda que esto es básico. Usando estas ideas básicas puede aprovechar de forma segura la potencia de los hilos.

public class WorkState 
{ 
    private readonly Object _Lock = new Object(); 
    private Int32 _State; 

    public Int32 GetState() 
    { 
     lock (_Lock) 
     { 
      return _State; 
     } 
    } 

    public void UpdateState() 
    { 
     lock (_Lock) 
     { 
      _State++; 
     } 
    } 
} 

public class Worker 
{ 
    private readonly WorkState _State; 
    private readonly Thread _Thread; 
    private volatile Boolean _KeepWorking; 

    public Worker(WorkState state) 
    { 
     _State = state; 
     _Thread = new Thread(DoWork); 
     _KeepWorking = true;     
    } 

    public void DoWork() 
    { 
     while (_KeepWorking) 
     { 
      _State.UpdateState();     
     } 
    } 

    public void StartWorking() 
    { 
     _Thread.Start(); 
    } 

    public void StopWorking() 
    { 
     _KeepWorking = false; 
    } 
} 



private void Execute() 
{ 
    WorkState state = new WorkState(); 
    Worker worker = new Worker(state); 

    worker.StartWorking(); 

    while (true) 
    { 
     if (state.GetState() > 100) 
     { 
      worker.StopWorking(); 
      break; 
     } 
    }     
} 
+0

No es que una cola de mensajes sea adecuada para ningún propósito ... – Thorarin

+0

¿No está enviando mensajes? – ChaosPandion

+1

Estamos tratando de leer la instancia de objeto disponible en un hilo en otro hilo, y tenemos una restricción para mantener la variable global/estática, ¿hay alguna buena idea para lograrlo? –

3

Cuando inicia un hilo, está ejecutando un método de alguna clase elegida. Todos los atributos de esa clase son visibles.

Worker myWorker = new Worker(/* arguments */); 

    Thread myThread = new Thread(new ThreadStart(myWorker.doWork)); 

    myThread.Start(); 

su hilo de rosca se encuentra ahora en el método DoWork() y se puede ver ninguna Atrributes de myWorker, que pueden ellos mismos ser otros objetos. Ahora solo debe tener cuidado para tratar con los casos de tener varios hilos que tocan esos atributos al mismo tiempo.

+0

sí .. Tu idea es muy útil, déjame explicar mi situación aquí como Estamos tratando de leer la instancia de objeto disponible en un hilo en otro hilo, y tenemos una restricción para mantener la variable global/estática, ¿hay alguna buena idea? para lograrlo? –

+0

No dio detalles, simplemente repitió su pregunta original. – ChaosPandion

+0

Por favor, lea mi comentario sobre su pregunta. Quiero seguir explicando pero necesito tu ayuda. – djna

7

mira el siguiente código de ejemplo:

public class MyWorker 
{ 
    public SharedData state; 
    public void DoWork(SharedData someData) 
    { 
     this.state = someData; 
     while (true) ; 
    } 

} 

public class SharedData { 
    X myX; 
    public getX() { etc 
    public setX(anX) { etc 

} 

public class Program 
{ 
    public static void Main() 
    { 
     SharedData data = new SharedDate() 
     MyWorker work1 = new MyWorker(data); 
     MyWorker work2 = new MyWorker(data); 
     Thread thread = new Thread(new ThreadStart(work1.DoWork)); 
     thread.Start(); 
     Thread thread2 = new Thread(new ThreadStart(work2.DoWork)); 
     thread2.Start(); 
    } 
} 

En este caso, la clase de hilo MyWorker tiene una variable state. Inicializamos con el mismo objeto . Ahora puede ver que los dos trabajadores acceden al mismo objeto SharedData. Los cambios realizados por un trabajador son visibles para el otro.

Tiene algunos problemas restantes.¿Cómo sabe el trabajador 2 cuando cambios han sido realizados por el trabajador 1 y viceversa? ¿Cómo previene cambios conflictivos? Quizás lea: this tutorial.

+1

Yap ... está cerca pero no es exacto ... aquí dos hilos pero la misma instancia de la clase myworker, para mí dos ejemplos de la clase MyWorker (work1 y work2) en diferentes hilos y quiero leer datos del trabajo1 en thread2 ... ¿cómo podemos hacerlo? –

+0

En ese caso, deberá pasar el objeto work1 a thread2. Puede hacerlo utilizando ParameterizedThreadStart en lugar de ThreadStart. – Aamir

+0

@Amir espero que no te importe, ajusté el ejemplo para que coincida con la descripción de Jaswant – djna

Cuestiones relacionadas