在下面的第二次嘗試中,我收到警告“釋放未持有的鎖'csCriticalSection'”。
這是我的代碼,但沒有所有 ADO 代碼。我不知道為什么會收到此警告,因為如果Execute()函式失敗,catch將運行一個LeaveCriticalSection函式。如果Execute()函式成功,我呼叫LeaveCriticalSection.
#include <windows.h>
#include <synchapi.h>
#include <comdef.h>
#include <conio.h>
CRITICAL_SECTION csCriticalSection;
_ConnectionPtr connectioncreate = nullptr;
_RecordsetPtr recordset = nullptr;
int main()
{
InitializeCriticalSectionAndSpinCount(&csCriticalSection, 4000);
// *** all ADO code here ***
//
// *** all ADO code here ***
BOOL bRanLeaveCriticalSection = FALSE;
try
{
EnterCriticalSection(&csCriticalSection);
// Run an SQL command with ADO.
/*
connectioncreate->BeginTrans();
connectioncreate->Execute(sSQL.data(), nullptr, adCmdText);
connectioncreate->CommitTrans();
*/
LeaveCriticalSection(&csCriticalSection);
bRanLeaveCriticalSection = TRUE;
}
catch (CONST _com_error& err)
{
connectioncreate->CommitTrans();
if (bRanLeaveCriticalSection == FALSE)
LeaveCriticalSection(&csCriticalSection);
}
try
{
// From compiler at the next line "if (recordset)":
// Warning C26117 Releasing unheld lock 'csCriticalSection'
if (recordset)
if (recordset->State == adStateOpen)
recordset->Close();
}
catch (CONST _com_error& err)
{
err;
}
_getch();
}
誰能幫我解決我收到此警告的原因以及如何解決?
uj5u.com熱心網友回復:
您csCriticalSection在使用它之前沒有進行初始化,例如:
...
CRITICAL_SECTION csCriticalSection;
...
int main()
{
InitializeCriticalSection(&csCriticalSection); // <-- ADD THIS
...
DeleteCriticalSection(&csCriticalSection); // <-- ADD THIS
}
而且,你真的不應該使用bRanLeaveCriticalSection,這只是糟糕的代碼設計。
您可以改用__try/__finally塊(如果您的編譯器支持),例如:
...
CRITICAL_SECTION csCriticalSection;
...
int main()
{
...
try
{
EnterCriticalSection(&csCriticalSection);
__try
{
// Run an SQL command with ADO.
}
__finally
{
LeaveCriticalSection(&csCriticalSection);
}
}
catch (CONST _com_error& err)
{
...
}
...
}
但是,最好的選擇是使用 RAII 包裝器,讓它為您呼叫EnterCriticalSection(),LeaveCriticalSection()例如:
struct CRITICAL_SECTION_LOCK
{
CRITICAL_SECTION &m_cs;
CRITICAL_SECTION_LOCK(CRITICAL_SECTION &cs) : m_cs(cs) {
EnterCriticalSection(&m_cs);
}
~CRITICAL_SECTION_LOCK() {
LeaveCriticalSection(&m_cs);
}
};
...
CRITICAL_SECTION csCriticalSection;
int main()
{
...
try
{
CRITICAL_SECTION_LOCK lock(csCriticalSection);
// Run an SQL command with ADO.
}
catch (CONST _com_error& err)
{
...
}
...
}
或者更好的是,改用 C std::mutex,并使用適當的 RAII 鎖std::lock_guard,例如:
#include <mutex>
std::mutex mtx;
...
int main()
{
try
{
std::lock_guard<std::mutex> lock(mtx);
// Run an SQL command with ADO.
}
catch (CONST _com_error& err)
{
...
}
...
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/442483.html
上一篇:嘗試寫入記憶體映射檔案時出現問題,在兩個行程之間共享(32位->64位)
下一篇:如何從pid獲取命令列引數?
