簡體   English   中英

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

[英]ASP.NET C# external SDK not thread-safe

我在 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 的查詢中,例如,當我同時向兩家公司循環 100 次調用 cURL 中的 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 的格式及其使用方式,可能存在使調用並行的解決方案。

用一些代碼、示例等更新問題,可能會讓我更清楚。

這可能是啟動多個應用程序而不是一個應用程序並將它們用作池,從同一個庫創建多個對象等等。

我已發表評論要求澄清; 我希望您處於可以重新設計此功能的開發階段。

一般來說,ASP.NET 對於非平凡的同步進程來說真的很差。 很容易耗盡線程池,並且從“桌面”或 RPC 架構轉移時,像您描述的並發問題並不少見。

我強烈建議將這些類型的操作的 WebAPI/ASP.NET 架構更改為基於隊列/任務的方法。 客戶端提交任務,然后輪詢/訂閱完成結果。 這將允許您設計后端以任何必要的方式運行,以防止由於共享庫而導致的數據損壞問題。 也許每個公司都有一個處理請求的長期后端流程 - 我不太了解您提出明智建議的需求,但您在這里有很多選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM