How to share data between different threads In C# using AOP?

前端 未结 4 1476
名媛妹妹
名媛妹妹 2020-11-28 08:15

How to share data between different threads In C# without using the static variables? Can we create a such machanism using attribute?

Will Aspect oriented programmin

相关标签:
4条回答
  • 2020-11-28 08:33

    Look at the following example code:

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

    In this case, the thread class MyWorker has a variable state. We initialise it with the same object. Now you can see that the two workers access the same SharedData object. Changes made by one worker are visible to the other.

    You have quite a few remaining issues. How does worker 2 know when changes have been made by worker 1 and vice-versa? How do you prevent conflicting changes? Maybe read: this tutorial.

    0 讨论(0)
  • 2020-11-28 08:35

    When you start a thread you are executing a method of some chosen class. All attributes of that class are visible.

      Worker myWorker = new Worker( /* arguments */ );
    
      Thread myThread = new Thread(new ThreadStart(myWorker.doWork));
    
      myThread.Start();
    

    Your thread is now in the doWork() method and can see any atrributes of myWorker, which may themselves be other objects. Now you just need to be careful to deal with the cases of having several threads all hitting those attributes at the same time.

    0 讨论(0)
  • 2020-11-28 08:41

    You can't beat the simplicity of a locked message queue. I say don't waste your time with anything more complex.

    Read up on the lock statement.

    lock

    EDIT

    Here is an example of the Microsoft Queue object wrapped so all actions against it are 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

    I hope this example helps. Remember this is bare bones. Using these basic ideas you can safely harness the power of threads.

    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 讨论(0)
  • 2020-11-28 08:54

    You can pass an object as argument to the Thread.Start and use it as a shared data storage between the current thread and the initiating thread.

    You can also just directly access (with the appropriate locking of course) your data members, if you started the thread using the instance form of the ThreadStart delegate.

    You can't use attributes to create shared data between threads. You can use the attribute instances attached to your class as a data storage, but I fail to see how that is better than using static or instance data members.

    0 讨论(0)
提交回复
热议问题