Search code examples
c#.netasynchronouscom-interoptask-parallel-library

Invoke COM Interop with timeout


I was wondering how to accomplish this. I have a COM object whose operations sometimes take long, additionally I noticed, it has it's own timeout 20 minutes if something goes wrong. This is unacceptable for the client program to wait so long.

Therefore I'm thinking about invoking the COM operation on another thread and after certain timeout just kill the thread.

I have COM helper to do the invokation via reflection, which is synchronous:

ComInvoke.Get<bool>(dcomSrv, "Launched");

this gets a boolean property from COM instance

and I want to wrap this using Task:

var task = Task.Factory.StartNew<bool>(() =>
            {
                return ComInvoke.Get<bool>(dcomSrv, "Launched");
            });

if (task.Wait(5000) == false)
            {
                task.Dispose();
                throw new Exception("Task timeout");
            }

The thing is that in the task there is no loop where I could make use of cancelation token.

What do you think, is this a good solution or do you have something better?

Thank you!


Solution

  • Task::Dispose will not actually stop the Task's underlying thread and, because the TPL uses the ThreadPool by default to schedule it's work, this logic will consume a ThreadPool thread for the full 20 minutes that the DCOM object is blocking it. As a matter of fact, I'm pretty sure you'll get an exception if you call Dispose on an uncompleted Task.

    This is a case where TPL probably shouldn't be used and you just want to spin up your own Thread instance and just Abort it if it does not complete in the desired amount of time.