views:

48

answers:

1

Hi. I have a 3rd party COM object I call that uses a event callback to signal it has completed its task.

obj.Start();  

then sometime later it will raise an event to say it is done.

void OperationFinished()

I would like to be able to do this operation synchronously and have tried to use AutoResetEvents to handle this

e.g.

obj.Start();
m_autoReset.WaitOne();

and in the event handler:

void OperationFinished()
{
    m_autoReset.Set();
}

but it seems that both the Set() and the WaitOne() are on the same thread so it gets stuck. Is there a simple way to handle this?

+2  A: 

Here's a quick thought off the top of my head. A bit verbose, but don't see why this wouldn't do the trick.

private readonly object m_locker = new object();
private volatile bool m_complete;

. .

lock (m_locker)
{
    m_complete = false;
}

obj.Start();
while (true)
{
    bool complete

    lock (m_locker)
    {
        complete = m_complete;
    }

    if (complete)
    {
        break;
    }

    Thread.Sleep(500); // Give a half-second wait to see if we're done.  YMMV.
}

. .

void OperationFinished()
{
    lock (m_locker)
    {
        m_complete = true;
    }
}
Jesse C. Slicer
While I have certainly written code like that, I think it may be better to sleep a larger amount. Say 1 second at a time if the operation normally takes 10 seconds to run. Otherwise you burn a lot of cycles on context switches.
Jonathan Allen
Jesse, it still didnt work for me,...until I added Application.DoEvents() before your Thread.Sleep(0) then it worked. Would love to know why that would be?
freddy smith
COM. I am guessing that Application.DoEvents lets your COM objects do their message pumping.
Jonathan Allen
P.S. Never use Thread.Sleep(0). http://www.bluebytesoftware.com/blog/PermaLink,guid,1c013d42-c983-4102-9233-ca54b8f3d1a1.aspx
Jonathan Allen
@Jonathan - Good point on the context-switching frequency!
Jesse C. Slicer