I am planning a different approach - have written half of the code, but it is not ready for testing yet. In my case, it is one subsystem written in C++, others in C#. Rather than messing around with P/invoke and all sorts of parameter transfer, synchronization and whathaveyou, I run it as two processes. The two subsystems have limited, and structurally very simple, data interchange. I find it far easier to exchange those data through a named pipe. The data format is application specific, but as these two subsystems belong to the same application, it is like an internal API with no more need to adhere to a standard than any other internal interface. I like strong isolation between subsystems and modules. It gives greater freedom within each subsystem/module, and it keeps the architecture clean. And it makes the system flexible: If I later want to replace that C++ subsystem with one written in Cobol, say :-), I could do so without any effect on the C# part. Well, if I could access that Cobol code through the same P/invoke interface, it might be similar, but now I don't have to worry about that at all. I am considering the same approach even when the subsystems are all in C#: Threads are fair enough, but do not provide the same isolation as separate processes. When different tasks really are independent (such as one monitoring external equipent/events, the other one interacting with the user; the only common data are the summary reports from the monitor process), they might as well be implemented and run as completely separate entities. Two simple entities are better than one complex.