How to Share Data Between Different Threads in C# Using Aop

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

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.

AOP can be use to share data among different running threads in application process?

Aspect orientated programming is ideal when you need to reduce "cross cutting" functionality within your code base. What this means is you have common code (logging, security) that classes need to implement but you cannot abstract that functionality into base classes.

So, AOP is really taking small these pieces of functionality and embedding them, at runtime or compile time, into your code where the "cross cutting" functionality is present.

Resources

Currently, AOP is not built into C# but there the following frameworks can build AOP:

  • AspectDng
  • NAspect
  • PostSharp
  • LOOM.Net
  • Spring.Net

AOP for thread data

Generally, using AOP to share data across threads is not the way to go. There are other techniques available for developers to do that:

  • [ThreadStaticAttribute] Append this attribute to fields to dictate to the .NET runtime that the following field will be unique to multiple threads

  • Synchronization (most common technique) Use Mutexes, Semaphores, ReaderWriter locks and EventWaitHandles to synchronize access to local or global data from multiple threads. In C#, the lock statement is syntactic sugar for the Monitor class, which can be used to "lock" access to an object from a single thread.

sharing variables between thread and class

You can put a lock on your code. Each thread will wait on your lock statement and then will go inside your new data creation:

private void OnTimer(object sender, ElapsedEventArgs status)
{
GetNewData();
}

object lockCheck = new object();
public void GetData(ref List<double> data, int index)
{
lock(lockCheck)
{
if (index < m_data.Length)
{
data = new List<double>(m_data[index]);
}
else
{
data = new List<double>();
}
}
}

What is the recommended way to pass data back and forth between two threads using C#

You should use immutable data transfer objects.

As long as a simple object is deeply immutable (meaning that neither it nor any of it's properties can change), there is nothing wrong with using it on multiple threads.

To pass the instances between threads, you might want to use a pseudo-mutable thread-safe stack. (This depends on your design)

Threading, let one thread know the others progress

One very simple way to do this is with BackgroundWorker. It already provides an event to report progress.

How to share data among multiple views

While working with this you have multiple views, but still one application. The most important thing here is mentioned at MSDN you have linked:

Each window operates in its own thread.

This complicates a situation in case of sharing data. As you have one application, you can share some data in app class, but you must look out for few things:

  • UI elements can be accessed only via Dispatcher thread and in this case the one that owns them (so you cannot share this),
  • concurrent access to collections - as there are few threads that can simultaneously access/modify them, use Thread-Safe collections, also some help here,
  • in case of synchronization, you also may need some primitives to steer your application workflow,
  • race conditions - design your app with caution.

Some more help you can find at many blogs/posts. For example at Alabhari's one.

How do I access variables from a different thread?

Accessing a control from different threads

In WinForms App you can ony access directly a Control from the thread it was created.
To do such a task you will need to use InvokeRequired property of a control to see if you must use Invoke inorder to force a call of the action from the original thread.

A public method that might be accessed from any thread including the original would look like this:

public void run() {
if (label1.InvokeRequired) //Is this method being called from a different thread
this.Invoke(new MethodInvoker(()=> label1.Text = CONNECTING));
else //it's cool, this is the original thread, procceed
label1.Text = CONNECTING;
}


But if you are absolutly sure that run() method will be called only from the thread, consider not even checking if InvokeRequired and immediatly call Invoke
Further information: http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx

Stopping a thread in progress

  • Simples is to use t1.Abort(); method of a Thread. This will throw and exception forcing it to stop where ever it was. this is great for threads that do not do any long processing so stopping it won't cause any problems.

  • If you do do proccesing in your thread, which means you can't just stop it in the middle then I suggest you to use a boolean that will indicate that the thread must cancel ASAP.


private bool isCancelRequired = false;
public void run() {
while(true) {
//do long processing..
if (isCancelRequired)
break;
}
}
  • More advanced methods: http://www.yoda.arachsys.com/csharp/threads/shutdown.shtml


Related Topics



Leave a reply



Submit