如何在 C# 中使用 AOP 在不同线程之间共享数据?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1360533/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 15:37:50  来源:igfitidea点击:

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

c#multithreading

提问by Jaswant Agarwal

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

如何在不使用静态变量的情况下在 C# 中的不同线程之间共享数据?我们可以使用属性创建这样的机制吗?

Will Aspect oriented programming help in such cases?

在这种情况下,面向方面的编程会有帮助吗?

To acheive this all the different threads should work on single object?

为了实现这一点,所有不同的线程都应该在单个对象上工作吗?

采纳答案by Franci Penov

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

您可以将对象作为参数传递给 ,Thread.Start并将其用作当前线程和启动线程之间的共享数据存储。

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 ThreadStartdelegate.

如果您使用ThreadStart委托的实例形式启动线程,您也可以直接访问(当然使用适当的锁定)您的数据成员。

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.

您不能使用属性在线程之间创建共享数据。您可以使用附加到您的类的属性实例作为数据存储,但我看不出这比使用静态或实例数据成员更好。

回答by ChaosPandion

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 lockstatement.

阅读锁定语句。

lock

EDIT

编辑

Here is an example of the Microsoft Queue object wrapped so all actions against it are thread safe.

这是一个 Microsoft Queue 对象包装的示例,因此针对它的所有操作都是线程安全的。

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

编辑 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;
        }
    }                   
}

回答by djna

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.

您的线程现在在 doWork() 方法中,可以看到 myWorker 的任何属性,这些属性本身可能是其他对象。现在您只需要小心处理多个线程同时访问这些属性的情况。

回答by Aamir

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 MyWorkerhas a variable state. We initialise it with the sameobject. Now you can see that the two workers access the sameSharedData object. Changes made by one worker are visible to the other.

在这种情况下,线程类MyWorker有一个变量state。我们用同一个对象初始化它。现在您可以看到两个 worker 访问同一个SharedData 对象。一名工人所做的更改对另一名工人可见。

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

你还有很多问题。工人 2 如何知道工人 1何时进行了更改,反之亦然?您如何防止发生冲突的更改?也许阅读:本教程