Share via


Communication between Threads

Question

Tuesday, April 3, 2007 6:22 PM

 

Hi,

 

I am somewhat new to C#.  I am creating this object,Controller, from a main thread, Mediator, and would like it to run asynchonously and have the ability to send messages back and forth to each other.  Since I need this Controller to run on its own I have created a thread and created the Controller within that thread.  Since I am creating several of these threads/Controllers creating events to do the communication would get very complicated as I only want to send the message to one Controller from the Mediator.  Is there a way to pass a copy of the original Mediator so that the two objects can communicate with method calls or would this violate Threading constraints, if so is there an easier way around this than creating a new event specific for each Controller.

 

Thanks in advance,

Jason

All replies (5)

Tuesday, April 3, 2007 9:48 PM âś…Answered

There are no ends to the messaging...usually the easiest (and if safe) is the best route. There is nothing wrong with your idea.

Check out this only article on Threading in C# which talks about threading but has some examples of other types of messaging which you could use, look for the queue example lower down.

Also not related messaging, but on threading one may experience these issues when using threads:

  1. My application hangs if I close it while I have child workers (threads).
  2. I stop my thread using Thread.Abort, but it continues to run.

I have a post in my blog (C# Threading Worker Class) which has an example class to play with synchronous and asynchronous threads and it shows how to handle those above situations.


Tuesday, April 3, 2007 8:56 PM

Is this one directional or bi-directional communication?

One basic way of messaging which is a one-to-many is to create a common thread safe place to send messages and receive messages. Here is sample code where a client can place messages in the queue and a consumer(?) can receive the messages in a thread safe manner. The trick is to use a basic lock to ensure that messages are not added when being removed.
 

Code Snippet

 

private Queue<string> _Messages = new Queue<string>();
private object _SyncObject = new object();

public List<string> Messages
{
    get
    {
        List<string> retMessages = new List<string>();
        lock (locker)
        {
           if (_myQueue.Count > 0)
               retMessages.AddRange(_Messages);

            _Messages.Clear();
        }

       return retMessages;
    }
}

public void SetMessage( string message )
{
    lock (_SyncObject)
        _Messages.Enqueue(message);

}


Tuesday, April 3, 2007 9:03 PM

This would be bi-directional somewhat one to one, as the client can talk to many consumers but only sends a particular message to one consumer, in which case could I just create multiple queues for each consumer, and then one queue for the client that all the consumers add to?

 

Thanks for the reply


Wednesday, April 4, 2007 7:00 AM

Hi Jason

You must be using Thread class to create threads and starting them using Thread.Start. The Start method takes an object as a parameter which you could use to pass the Mediator object. It would be better if you pass that as IMediator interface instead of the direct class type instance. This [IMediator] would provide only access to what is required for Controller from the thread.

Hope that helps.

Regards


Thursday, April 5, 2007 3:02 AM

It gets a little difficult with "messages".  .NET doesn't really provide access to a message queue for a thread.

 

One thing you can do is provide an object accessible to both threads and use a ReaderWriterLock object to synchronize access to the object and two EventWaitHandle-derived objects to inform each other of changes.  Each thread would the use ReaderWriterLock.AcquireWriterLock when "writing" to the shared object, and ReaderWriteLock.AcquireReaderLock when it wants to "read" from the shared object. When done writing each thread would call EventWaitHandle.Set to signal to the other thread that new data is available.

The drawback is that each thread really needs to be waiting for an event to occur for it to handle it.  If it's not waiting for the event, it runs the risk of missing it.