调用 COM Interop 并设置超时

发布于 2024-10-21 22:51:57 字数 697 浏览 3 评论 0原文

我想知道如何实现这一点。我有一个 COM 对象,其操作有时需要很长时间,另外我注意到,如果出现问题,它有自己的超时 20 分钟。这对于客户端程序来说等待这么长时间是不可接受的。

因此,我正在考虑在另一个线程上调用 COM 操作,并在一定的超时后终止该线程。

我有 COM 助手通过反射进行调用,这是同步的:

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

这从 COM 实例获取一个布尔属性

,我想使用任务包装它:

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

if (task.Wait(5000) == false)
            {
                task.Dispose();
                throw new Exception("Task 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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

动次打次papapa 2024-10-28 22:51:57

Task::Dispose 实际上不会停止 Task 的底层线程,并且由于 TPL 默认情况下使用 ThreadPool 来安排其工作,因此此逻辑将消耗 ThreadPool 线程DCOM 对象阻止它的整整 20 分钟。事实上,我很确定如果您对未完成的 Task 调用 Dispose,您会遇到异常。

在这种情况下,可能不应该使用 TPL,您只想启动自己的 Thread 实例,如果它未按所需数量完成,则Abort 它的时间。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文