Comment partager des données entre différents threads en C # en utilisant AOP?
comment partager des données entre différents threads en C# sans utiliser les variables statiques? Pouvons-nous créer un tel machanisme en utilisant un attribut?
la programmation axée sur les aspects peut-elle être utile dans de tels cas?
Pour réaliser ce tous les différents fils devrait fonctionner sur un seul objet?
4 réponses
vous pouvez passer un objet comme argument à Thread.Start
et l'utiliser comme stockage de données entre le fil et le thread d'initialisation.
vous pouvez aussi accéder directement (avec le verrouillage approprié, bien sûr) à vos membres de données, si vous avez démarré le thread en utilisant la forme d'instance du ThreadStart
délégué.
vous ne pouvez pas utiliser d'attributs pour créer des données partagées entre les threads. Vous pouvez utiliser l'attribut instances attaché à votre classe en tant que stockage de données, mais je ne vois pas comment c'est mieux que d'utiliser des données statiques ou des données d'instance.
vous ne pouvez pas battre la simplicité d'une file d'attente de message verrouillée. Ne perdez pas votre temps avec quelque chose de plus complexe.
Lire sur le verrouillage déclaration.
EDIT
voici un exemple de L'objet Microsoft Queue enveloppé de sorte que toutes les actions contre lui sont thread safe.
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;
}
}
}
}
EDIT 2
j'espère que cet exemple permet. Rappelez-vous ceci est nu ossements. En utilisant ces idées de base, vous pouvez exploiter en toute sécurité la puissance des fils.
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;
}
}
}
regardez le code d'exemple suivant:
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();
}
}
Dans ce cas, la classe thread MyWorker
a une variable state
. Nous l'initialisons avec le objet. Maintenant vous pouvez voir que les deux ouvriers accèdent à la SharedData object. Les changements apportés par un travailleur sont visibles de l'autre.
vous avez encore quelques problèmes. Comment le travailleur 2 le sait-il?--6-->quand des modifications ont été apportées par le travailleur 1 et vice-versa? Comment faites-vous prévenir les changements conflictuels? Peut-être lire: ce tutoriel.
lorsque vous démarrez un thread, vous exécutez une méthode d'une classe choisie. Tous les attributs de cette classe sont visibles.
Worker myWorker = new Worker( /* arguments */ );
Thread myThread = new Thread(new ThreadStart(myWorker.doWork));
myThread.Start();
votre thread est maintenant dans la méthode doWork () et peut voir n'importe quels atrributes de myWorker, qui peuvent eux-mêmes être d'autres objets. Maintenant, vous avez juste besoin d'être prudent afin de traiter les cas d'avoir plusieurs threads toutes les frapper ces attributs en même temps.