gpt4 book ai didi

C# STAThread COMException 异常

转载 作者:太空狗 更新时间:2023-10-29 21:54:32 27 4
gpt4 key购买 nike

我有一个外部组件 (C++),我想从我的 C# 代码中调用它。

代码是这样的:

using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace dgTEST
{
class Program
{
[STAThread]
static void Main(string[] args)
{
ExtComponentCaller extCompCaller = new ExtComponentCaller();
result = extCompCaller.Call(input);

Thread t = new Thread(new ThreadStart(() =>
{
try
{
result = extCompCaller.Call(input);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}));

t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
}
}
}

所以问题是,在第一次调用时它运行良好,调用了外部组件,我得到了返回结果。

但是当我试图在另一个线程中调用它时,我得到了一个异常:System.InvalidCastException:无法转换类型为“System.__ComObject”的 COM 对象 ...。我确定抛出了这个异常,因为 STAThread。因为如果我从 Main 函数中删除 [STAThread] 属性,那么第一次调用外部组件时会发生同样的情况,但效果很好。

如何从另一个线程调用这个外部组件来摆脱这个异常?

更新----------------

现在发生了其他疯狂的事情。当我使用 F5 从 Visual Studio 启动程序时,问题也出现在第一次调用中,但是当我直接执行二进制 .exe 文件时,它正在工作(从另一个线程它不是 :( )。如果我将构建从 Debug 切换到 Release 并使用 F5 从 Visual Studio 启动它,第一个调用再次工作。

为什么会这样?

提前感谢您的帮助!

最好的问候,佐力

最佳答案

线程从来都不是一个小细节。如果没有明确记录代码以支持线程,那么 99% 的可能性是它不支持它。

显然这个组件不支持线程。创建另一个 STA 线程并不是 Elixir ,它仍然是一个不同的线程。 InvalidCastException 告诉您它还缺少编码来自工作线程的调用所需的代理/ stub 支持,就像您尝试创建的线程一样。需要对非线程安全的代码进行线程安全调用。尽管您确实违反了 [STAThread] 的约定,但它必须泵出一个消息循环。消息循环允许从工作线程调用非线程安全的组件。您从 Application.Run() 获得一个消息循环。

这就是责任停止的地方。它不是线程安全的,期间。即使修复您的主线程或要求供应商或作者为您提供代理/ stub ,您仍然没有完成您打算做的事情,它实际上不会在您创建的那个工作线程上运行。所以它必须看起来像这样:

    static void Main(string[] args)
{
Thread t = new Thread(new ThreadStart(() =>
{
ExtComponentCaller extCompCaller = new ExtComponentCaller();
result = extCompCaller.Call(input);
}));

t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
}

它在您进行调用的同一线程上创建对象,因此它是线程安全的。仍然存在此工作线程不泵送消息循环的问题,COM 组件往往依赖于此。您将从死锁或未运行的事件中找出这是否是一个问题。如果当您从主线程调用它时它在您的测试程序中已经正常工作,那么您可能可以不抽水。

关于C# STAThread COMException 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16100941/

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