Hi James,

I have had the same problem and came up with the following solution: I
wrote a class which provides an apartment for the com object. The usage is
simple:

ComApartment ca = new ComApartment();
ca.Invoke(new SomeHandler(someObject.SomeFunction), new object[]{par1,
par2});


public class ComApartment{
 private Thread _apartmentThread;
 private AutoResetEvent _apartmentEvent;
 private AutoResetEvent _apartmentEventResult;
 private Delegate _invokeDelegate;
 private object[] _invokeArgs;
 private object _invokeResult;
 private Exception _exception = null;
 private bool _terminate = false;

public ComApartment() {
 _apartmentThread = new Thread((new ThreadStart(ApartmentThreadHandler)));
 _apartmentThread.ApartmentState = ApartmentState.STA;
 _apartmentEvent = new AutoResetEvent(false);
 _apartmentEventResult = new AutoResetEvent(false);
 _apartmentThread.Start();
}

public void Terminate(){
 _terminate = true;
}

private void  ApartmentThreadHandler(){
  while (_terminate == false) {
  try{
   _apartmentEvent.WaitOne();
   _ exception = null;
   _invokeResult = null;
   _invokeResult = _invokeDelegate.DynamicInvoke(_invokeArgs);
   _ apartmentEventResult.Set();
  } catch (Exception e){
   _exception = e;
   _apartmentEventResult.Set();
  }
}

public object Invoke(Delegate del, object[] args ){
 lock(this){
  _invokeDelegate = del;
  _invokeArgs = args;
  _apartmentEvent.Set();
  _apartmentEventResult.WaitOne();
  if (_exception != null){
   throw new Exception("Invoke failed", _exception);
  }
  return _invokeResult;
 }
}

Alex.

You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced 
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to