2

I have a long running COM+ method that I need to be able to cancel from another thread. I am using C#/.NET to interact the COM+ objects. I configured both COM+ objects to have a "Free" threading model. This C# sample demonstrates how I intend to use the COM+ objects.

static void Main(string[] args)
{
    var sampleCOMClass = new SampleCOMObjectClass();
    var cancelToken = new CancelCOMObjectClass();
    try
    {
        Task.Factory.StartNew(() =>
        {
            Thread.Sleep(TimeSpan.FromSeconds(10));
            cancelToken.Cancel(); // this method never makes it to COM
            Console.WriteLine("Cancelled!");
        });
        sampleCOMClass.LongProcess(cancelToken);
    }
    finally
    {
        Marshal.ReleaseComObject(sampleCOMClass);
        Marshal.ReleaseComObject(cancelToken);
    }
}

My long running process correctly checks the cancellation token to determine if we should finish processing, but the Cancel method never makes it to the COM+ objects. It is as if the method is blocking, waiting for LongProcess to finish. I don't know why it is doing this, because I thought the "Free" threading model allowed the implementations to manage synchronization.

Here is a BitBucket repository with a minimal example to reproduce. https://bitbucket.org/theonlylawislove/so-blocking-com-call

Why is Cancel never getting called/blocking?

CancelCOMObject

STDMETHODIMP CCancelCOMObject::Cancel(void)
{
    _isCancelled = VARIANT_TRUE;
    return S_OK;
}

STDMETHODIMP CCancelCOMObject::get_IsCancelled(VARIANT_BOOL* pVal)
{
    *pVal = _isCancelled;
    return S_OK;
}

SampleCOMObject

STDMETHODIMP CSampleCOMObject::LongProcess(ICancelCOMObject* cancel)
{
    VARIANT_BOOL isCancelled = VARIANT_FALSE;
    while(isCancelled == VARIANT_FALSE)
    {
        Sleep(1000);
        cancel->get_IsCancelled(&isCancelled);
    }
    return S_OK;
}
4

1 回答 1

3

原来我的 COM+ exe 有这个。

#define _ATL_APARTMENT_THREADED

删除它解决了我的问题。

奇怪的是,ATL 简单对象向导在指定“免费”线程模型时没有提及/修改这一点。

很高兴知道谁投票结束了这个问题。这是完全有效的。

于 2014-05-04T17:15:20.733 回答