c# - 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 但尚未开始请求数据。
解决方案
您需要分享有关 ActiveX SDK 的更多信息(实际上没有这样的东西)。ActiveX 共有三种类型
(这里有很好的解释)
ActiveX EXE:与独立的 EXE 文件不同,ActiveX EXE 文件旨在用作 OLE 服务器,它只不过是一个旨在与另一个程序共享信息的程序。它有一个 .EXE 文件扩展名。
ActiveX DLL:ActiveX DLL 文件不能单独使用。相反,这些类型的文件包含设计为在创建独立程序时用作构建块的子程序。它有一个 .DLL 文件扩展名。
ActiveX 控件:与 ActiveX DLL 或 ActiveX EXE 文件不同,ActiveX 控件文件通常提供可以在其他程序中重复使用的子程序和用户界面。它具有 .OCX 文件扩展名。
根据 SDK 的格式和它的使用方式,可能有一些解决方案可以使调用并行。
用一些代码、示例等更新问题,可能会让我更加了解。
这可能是启动多个应用程序而不是一个应用程序并将它们用作池,从同一个库创建多个对象等等。
推荐阅读
- java - 未能在项目 libnd4j 上执行目标 org.bytedeco:javacpp:1.5.3:build (javacpp-cppbuild-compile):
- css - 退出时的 CSS 擦除动画
- vba - 将单词图与单词表链接
- r - 如何有效计算R中栅格单元周围一定距离内的空间点数?
- java - Spring Integration - SQS 消息的异步服务激活器
- c++ - C++:用整数移动语义
- devextreme - 如何将复选框添加到 dxDataGrid 分组行
- python - 如何为 AOT 编译的 numba 扩展指定目标目录?
- android - 是否可以使用手机的 IMU 来改善用户的步行路径?
- javascript - 如何以角度合并多个数组