首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ASP.NET C#外部SDK不是线程安全的

ASP.NET C#外部SDK不是线程安全的
EN

Stack Overflow用户
提问于 2019-12-06 21:05:15
回答 2查看 320关注 0票数 4

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

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

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

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

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

我能想到的唯一解决方案是在API为用户获取响应时“锁定”API。还有别的解决办法吗?如果没有,有关于如何在C#中这样做的指针吗?

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

当我使用SDK时,锁只需要激活(这可能是请求时间的99% )。

编辑1:

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

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

代码语言:javascript
运行
复制
            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的值将显示在我对公司A的查询中,例如,当我在cURL中对两个公司同时调用100个API时。它不是每次都这么做,只是为了一些查询。可能是当调用打开公司-B的SDK时,而对公司-A的调用已经连接到SDK,但还没有开始请求数据。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-06 23:37:01

我已经发布了一条评论,要求澄清;我希望您正处于开发阶段,您可以重新设计这个特性。

一般来说,ASP.NET对于非平凡的同步进程来说是非常糟糕的。很容易耗尽线程池,在从“桌面”或RPC体系结构迁移时,您所描述的并发问题并不少见。

我强烈建议将这些操作的WebAPI / ASP.NET架构更改为基于队列/任务的方法。客户端提交一个任务,然后轮询/订阅完成结果。这将允许您设计后端,以便以任何必要的方式操作,以防止共享库导致的数据损坏问题。也许每个处理请求的公司都有一个长期存在的后端流程--我对您的需求不太了解,无法提出明智的建议,但是您在这里有很多选择。

票数 0
EN

Stack Overflow用户

发布于 2019-12-06 21:38:23

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

(很好的解释)

ActiveX EXE:与单独的EXE文件不同,ActiveX EXE文件被设计为OLE服务器,它只不过是一个设计用来与另一个程序共享信息的程序。它有一个.EXE文件扩展名。 ActiveX DLL: ActiveX DLL文件不打算自己使用。相反,这些类型的文件包含在创建独立程序时作为构建块而设计的子程序。它有一个.DLL文件扩展名。 ActiveX控件:与ActiveX DLL或ActiveX EXE文件不同,ActiveX控制文件通常同时提供子程序和用户界面,可以在其他程序中重用。它有一个.OCX文件扩展名。

基于SDK的格式和它的使用方式,可能会有并行调用的解决方案。

用一些代码、示例等来更新这个问题,可能会使我得到更多的启示。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59220326

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档