views:

95

answers:

2

I am dealing a big situation in architecture design flaw in multiple threading. I try to keep my application completely thread safe and avoid conflict with each others.

The problem I was aware was this:

Assume there are two threads, Thread A and Thread B.

Thread A is something that you'll see from Static Void Main method as the only thread.

Thread A create an object that have asynchronous methods of Start/Stop and apply event handling to that object.

When Start method was called in the object from Thread A, it creates a new thread for that object to process the information from object properties or inputs which is Thread B. (In my case, network receiving and sending processes in my own protocol.)

When object in Thread B completed in receiving a new information from the input or property, Thread B invoke the event in the object to pass the data along to Thread A.

The problem is, when the event was invoked, it was managed by Thread B instead. Thread B was suppose to run only on that object to continue to do the processing method, but instead it go through to another object and later have cross threading conflict between Thread A and Thread B when it is suppose to pass an event to Thread A for Thread A alone to handle that new output.

If Thread A is the one that initialize the object and the class it was running on, how come when the event was invoked, it runs on Thread B instead?

I needed Thread B to continue to loop forever and not interrupt the program by passing event information to Thread A.

Please excuse my English and Grammar and thank you for your patience. :-)

[EDIT x4] If you want to get the source code, it is located here: http://fcpfoundation.codeplex.com/ (It is up now.)

You can find the source code in the link above. I'm sorry if my explanation isn't clear. The reason I couldn't make an example code is that it simply too big.

+2  A: 

By default, a callback will occur in the Thread that's firing the callback (Thread B). That's because there is no one right way for Thread B to tell Thread A that it has something for it to execute. After all, when should Thread A execute it? You wouldn't want Thread B to actually interrupt Thread A, as it might be busy doing something important and interrupting it could leave the program in an invalid state to run the code that Thread B is providing. Imagine the following occurred:

  • Thread A asks for Thread B to tell it when X has occurred.
  • Thread A begins sorting a list of important information.
  • Thread B tells Thread A to stop what it's doing, because X has occurred.
  • Thread A starts responding to X, but it was in the middle of a sort, so the list is in an invalid state, causing problems in handling X.

In order for Thread A to do something based on X, it needs to get to a safe place where it's not busy doing something else. In the main UI thread of an application, this occurs in what's known as the message pump, where Windows is giving the application messages like "please paint yourself" or "the mouse just moved". You can use the message pump to post your own messages, using Control.Invoke to schedule some code to execute on the UI thread.

If Thread A is not the UI thread, you'll need to come up with your own design for how Thread A gets the message from Thread B and deals with it on its own time.

Dan Bryant
In some of my applications I tend up sending *all* events via the UI thread (or some other shared execution context) just to simplify the design and have a common set of valid assumptions. While this approach is not always the best or most efficient, I find that a working program (even if it could be better) is more desirable than a program that (randomly) fails.
pst
You also can have Thread A have it's own message pump through [Application.Run()](http://msdn.microsoft.com/en-us/library/ms157900.aspx)
Scott Chamberlain
A: 

Maybe this is oversimplifying the issue, but have you considered some sort of a threadsafe FIFO message pump? i.e. Thread B can post event notifications to a FIFO queue which Thread A monitors. Since it is "fire and forget", Thread B can post and continue on its way, not caring what Thread A is doing. Thread A can then monitor and pull messages out of the queue as deemed appropriate.

A public static instance of System.Collections.Queue or System.Collections.Generic.Queue are both thread safe.

joseph.ferris