首页 > 解决方案 > ASP.NET C# 外部 SDK 不是线程安全的

问题描述

我在 ASP.NET/C# 中有一个 Web API。

它使用外部 32 位 ActiveX SDK 与第三方应用程序通信。

根据我的测试,当我们同时连接两个不同的用户时,该 SDK 会出现问题。第二个连接覆盖第一个。

如果我在两个 cURL 循环中调用我的 API,一个与 userA 连接,另一个与 userB 连接,在某些情况下,对 userA 的调用将具有 userB 的结果。

我的代码中没有任何静态变量,没有一个肯定引用 SDK。

我能想到的唯一解决方案是在获取用户响应时“锁定”API。还有其他解决方案吗?如果没有,关于如何在 C# 中执行此操作的任何指针?

API 有多个控制器(想想客户/发票/付款/供应商),所有这些都使用相同的 SDK。因此,对 CustomerController 方法的调用也必须锁定对其他控制器的调用。

锁只需要在我使用 SDK 时处于活动状态(这可能是请求时间的 99%)。

编辑1:

SDK 名为“Interop.AcoSDK.dll”,它是 32 位的。Visual Studio 将该文件描述为“AcoSDK 库”。它是 Acomba 的一个 SDK,一个会计程序。该程序本身具有非常古老的结构,其起源可以追溯到 DOS 的 80 年代(当时该程序被命名为 Fortune1000)。与 SDK 的交互真的不是现代的。

我已将 DLL 添加到我的项目中,为了使用它,我调用了两个部分。


            AcoSDKX AcoSDK = new AcoSDKX();
            int version = AcoSDK.VaVersionSDK;
            if (AcoSDK.Start(version) != 0)
            {
                throw new Exception("Failed to start SDK");
            }

            cie = new AcombaX();
            if (cie.CompanyExists(config.ciePath) == 0)
            {
                throw new Exception("Company not found");
            }

            int error = cie.OpenCompany(config.appPath, config.ciePath);
            if (error != 0)
            {
                throw new Exception("Failed to open company: " + cie.GetErrorMessage(error));
            }

            AcoSDK.User User = new AcoSDK.User
            {
                PKey_UsNumber = config.user
            };

            try
            {
                error = User.FindKey(1, false);
            }
            catch
            {
                throw new Exception("Failed to find user");
            }

            if (error != 0)
            {
                throw new Exception("Failed to find user");
            }

            error = cie.LogCurrentUser(User.Key_UsCardPos, config.pass);
            if (error != 0)
            {
                throw new Exception("Failed to login in Acomba: " + cie.GetErrorMessage(error));
            }

上面的cie属性是private AcombaX cie类中的。

从我的其他类调用该类来处理与 SDK 的连接。

我的另一个类将其声明为标准对象(非静态)。

config以上是指具有 API 请求所针对的公司/用户的属性的对象。可以拨打多家公司的电话。

目前,我的问题是调用不同的公司,数据最终会被混淆。因此,来自 Company-B 的值将显示在我对 Company-A 的查询中,例如,当我在 cURL 中同时向两家公司循环 100 次 API 调用时。对于某些查询,它不会每次都这样做,只是一段时间。可能当一个呼叫打开公司 B 的 SDK,而公司 A 的呼叫已经连接到 SDK 但尚未开始请求数据。

标签: c#asp.netiisactivex

解决方案


您需要分享有关 ActiveX SDK 的更多信息(实际上没有这样的东西)。ActiveX 共有三种类型

这里有很好的解释

ActiveX EXE:与独立的 EXE 文件不同,ActiveX EXE 文件旨在用作 OLE 服务器,它只不过是一个旨在与另一个程序共享信息的程序。它有一个 .EXE 文件扩展名。

ActiveX DLL:ActiveX DLL 文件不能单独使用。相反,这些类型的文件包含设计为在创建独立程序时用作构建块的子程序。它有一个 .DLL 文件扩展名。

ActiveX 控件:与 ActiveX DLL 或 ActiveX EXE 文件不同,ActiveX 控件文件通常提供可以在其他程序中重复使用的子程序和用户界面。它具有 .OCX 文件扩展名。

根据 SDK 的格式和它的使用方式,可能有一些解决方案可以使调用并行。

用一些代码、示例等更新问题,可能会让我更加了解。

这可能是启动多个应用程序而不是一个应用程序并将它们用作池,从同一个库创建多个对象等等。


推荐阅读