Ensuring that events raised by system.diagnostics process class happen in the parent thread
If you want a pretty solution, you would have to separate your data source (process in your case) from data processor (your while loop), hide implementations behind interfaces and then wire those interfaces together via events or aggregation. This is actually a pretty common problem called "Producer-Consumer", you should be able to find multiple decent implementations on the net. 

If you want a simple solution though, yours is probably fine. A few things you might want to improve:


Reduce nesting in your while loop to avoid arrow code. This can be done by using break/continue/return statements or by extracting logic to separate method or entity.
Depending on how often you receive messages and on how much time XXXtakes, you might want to release lock before calling XXX. 
You might want to wait for process to exit before returning form your method. This will ensure, that everything went smoothly, and there is no process left hanging somewhere due to some error in your code.
If XXX signature is not set in stone, you should probably replace strings with complex object:

class Message
{
   //use enum instead of hardcoded strings, such as "STDERR"
   public MessageType Type { get; set; }
   //actual data from process
   public string Data { get; set; }
} 


You should remove hardcoded "magic" strings either way.