gpt4 book ai didi

c# - 在多线程环境中处理 COM

转载 作者:太空狗 更新时间:2023-10-30 01:25:33 24 4
gpt4 key购买 nike

我正在尝试正确处理包含在 Visual Studio 生成的 RCW 中的遗留 VFP (FoxPro) COM 控件。该控件公开了一个我应该调用的 Destroy 方法,以允许控件正确地自行拆除。当发出处理 COM 实例的请求时,控件上的方法很有可能正在后台线程上执行。 VFP 是单线程单元模型,因此在调用 Destroy 时,只需将其添加到 VFP 执行堆栈即可。

理想情况下,调用 Destroy 是正确的做法,因为它允许 COM 实例清理一些资源。我担心的是,实例化 VFP COM 控件实际上会启动一个 VFP 语言运行时实例,该控件位于该实例中,并且该实例可能被锁定(无响应)。这个 COM 组件公开了一个大型企业级 20 年前遗留应用程序中的功能,我看到过这样的情况:一个 .NET 线程试图调用这个控件上的一个方法只是简单地阻塞而没有抛出错误(总是由遗留中的错误引起的) VFP代码)。这种情况并不经常发生,但它经常足以促使我构建一个实例管理器,它在后台线程中对 VFP COM 实例运行方法,并定期检查该线程是否被阻塞,如果是,则销毁COM 实例和线程并重新启动一个新的实例来监视。

这是处理可能正在执行后台方法的线程的正确方法吗?

我是否应该通过尝试调用 Destroy 方法以允许 COM 控件正确拆除来尝试变得更有趣?

if (_vfpThread != null)
{
try
{
if (_vfpThread.IsAlive)
_vfpThread.Abort();
}
catch (ThreadAbortException)
{ }
finally
{
_vfpThread = null;
}
}

if (_vfpInstance != null)
{
Marshal.ReleaseComObject(_vfpInstance);
_vfpInstance = null;
}

最佳答案

当基于 VFP 的 COM 对象(始终在 STA 单元中运行)上的方法调用挂起时,从另一个线程在同一 COM 对象上调用任何方法将阻塞,直到前一个调用返回(离开公寓)。这意味着,任何试图同时调用 Destroy() 的线程都将受到第一个线程的支配。如果该线程不知道主动退出,理论上它可以无限期地阻止处理线程。因此,换句话说,没有直接方法可以通过从另一个线程中调用 COM 对象上的另一个方法来要求第一个线程立即退出该方法。调用 _vfpThread.Abort() 应该可行,但这种方法的安全性在很大程度上取决于 VFP 类的内部结构。在许多情况下,由于它是遗留代码,它不会像 try/catch/finally 部分那样允许优雅退出,因此资源可能最终未被释放。 - 不好!

另一种方法是在某处(注册表、文件等)设置一个外部标志,该标志可供第一个线程从其正在执行的方法中读取。这当然要求 VFP 类知道必须从其 COM 发布的每个方法中读取标志,并迅速采取相应的行动。

另外,关于您的代码片段。在中止线程的代码中捕获 ThreadAbortException 只有在执行此代码的线程正在中止自身时才有意义。这会很尴尬,因为它可以直接从方法返回。 (或者,这个正在调用 _vfpThread.Abort() 的线程是否也可能被另一个线程中止?)在正常情况下,您需要包装在 ThreadAbortException 捕获器中的是第一个线程的主要代码,该代码执行对 COM 对象上所有这些业务方法的调用。理想情况下,您可以像 VFP 方法本身一样深入堆栈,代码可以在重新抛出异常之前优雅地关闭所有资源/表等。然后在传递给 ThreadStart 的 main 方法中,您将有一个类似的捕获器,只是它会从方法中和平返回,从而终止线程或将其释放到线程池。

关于c# - 在多线程环境中处理 COM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6685056/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com