你提供的代码段包含两个线程函数 GetUkeySizeThread
和 ConnectThread
,它们分别用于检查 UKEY 连接状态和网络连接状态。以下是对这两个函数的分析和一些改进建议:
1. GetUkeySizeThread
功能
- 检查 UKEY 的连接状态。
- 使用一个循环每隔 10 秒检查一次。
- 在日志文件中记录 UKEY 的连接状态。
改进建议
- 内存管理: 当前使用了
new
分配内存,但没有对应的delete
操作。应在不再需要arrUKEYInfo
时释放它。 - 异常处理: 在捕获异常后,可以考虑记录异常信息,以便后续调试。
示例代码改进
UINT CMainWnd::GetUkeySizeThread(LPVOID lparam)
{
CMainWnd* pWnd = (CMainWnd*)lparam;
CString modulePath = CUtility::GetModulePath(NULL);
CString filePath = modulePath + _T("ConnectionState.log");
Logger logger(filePath);
BOOL bConnect = FALSE;
while (TRUE)
{
try
{
int nKeyNum = UKEY_SIZE;
UKEYINFO* arrUKEYInfo = new UKEYINFO[nKeyNum];
char* arrInfo[2][5] = {
{ "FT", "PID_0713", "VID_096E", "", "USB" },
{ "WQ", "PID_0620", "VID_163C", "", "USB" }
};
for (int i = 0; i < nKeyNum; i++)
{
arrUKEYInfo[i].pszUKEYType = arrInfo[i][0];
arrUKEYInfo[i].pszPID = arrInfo[i][1];
arrUKEYInfo[i].pszVID = arrInfo[i][2];
arrUKEYInfo[i].pszCDROMPath = arrInfo[i][3];
arrUKEYInfo[i].pszClassDevice = arrInfo[i][4];
}
BOOL bInit = CUtility::InitializeUKEYInfo(nKeyNum, arrUKEYInfo);
int nPreKeySize;
char* pszDevName = NULL;
char* pszDevPath = NULL;
char* pszDriveLetter = NULL;
nPreKeySize = GetKeyList(&pszDevName, true, &pszDevPath, &pszDriveLetter);
bConnect = (nPreKeySize > 0);
ReleaseKeyList(pszDevName, pszDevPath, pszDriveLetter);
delete[] arrUKEYInfo; // 确保释放分配的内存
}
catch (const std::exception& e)
{
logger.log(CString("Exception: ") + e.what(), Logger::ERROR);
bConnect = FALSE;
}
catch (...)
{
logger.log("Unknown exception occurred.", Logger::ERROR);
bConnect = FALSE;
}
if (bConnect)
{
pWnd->m_pUkeyConnectStatus->SetText("Ukey已连接");
pWnd->m_pUkeyConnectStatus->SetTextColor(0x4ACB65);
logger.log("Ukey已连接", Logger::INFO);
}
else
{
pWnd->m_pUkeyConnectStatus->SetText("Ukey未连接");
pWnd->m_pUkeyConnectStatus->SetTextColor(0xCF4415);
logger.log("Ukey未连接", Logger::INFO);
}
::Sleep(10000); // 可以考虑使用条件变量来提高效率
}
}
2. ConnectThread
功能
- 测试与指定 URL 的 HTTP 连接。
- 使用一个循环遍历多个 URL 地址,记录并显示网络状态。
改进建议
- 资源管理: 对于创建的对象,应确保在所有情况下都正确关闭和删除(即使在出现异常时)。
- 错误处理: 可以扩展更多错误信息以便调试,并增强可读性。
示例代码改进
UINT CMainWnd::ConnectThread(LPVOID lparam)
{
CMainWnd* pWnd = (CMainWnd*)lparam;
CString modulePath = CUtility::GetModulePath(NULL);
CString filePath = modulePath + _T("ConnectionState.log");
Logger logger(filePath);
CInternetSession session(BANK_ADDR);
BOOL bConnect= FALSE;
session.SetOption(INTERNET_OPTION_SEND_TIMEOUT, 400);
char* tmpURL= CONNECT_TEST_URL;
// 循环处理每个 URL
while (*tmpURL != '\0')
{
CString strServer, strObject;
INTERNET_PORT wPort;
BOOL bURLParsed= AfxParseURL(tmpURL, dwType, strServer, strObject,wPort);
if (!bURLParsed) continue; // 如果无法解析则跳过
// 创建 HTTP 请求
try
{
auto pHttpConnection= session.GetHttpConnection(strServer,wPort);
auto pHttpFile= pHttpConnection->OpenRequest(CHttpConnection::HTTP_VERB_GET,strObject,NULL,1,NULL,NULL,internetFlags);
if(pHttpFile &&pHttpFile->SendRequest())
{
DWORD dwStateCode;
pHttpFile->QueryInfoStatusCode(dwStateCode);
if(dwStateCode==HTTP_STATUS_OK)
{
bConnect= TRUE;
}
}
if(pHttpFile!=NULL)
{
pHttpFile->Close();
delete pHttpFile;
}
}
catch(const CInternetException& e)
{
logger.log(CString("HTTP Error: ") + CString(e.m_dwError), Logger::ERROR);
}
tmpURL+= lstrlenA(tmpURL)+1;
}
session.Close();
if(bConnect)
{
pWnd->m_pWebStateImage->SetBkImage(_T("label\\label_webok.png"));
logger.log("网络已连接",Logger::INFO);
}
else
{
pWnd->m_pWebStateImage->SetBkImage(_T("label\\label_weberr.png"));
logger.log("网络断开",Logger::INFO);
}
return 0;
}
以上改进建议旨在提升代码的安全性、可读性和可维护性。在生产环境中,特别是在涉及多线程和外部资源操作时,资源管理非常重要。
内容由零声教学AI助手提供,问题来源于学员提问