[英]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.