> 1000次后,Requery()失败 [英] Requery() fails after >1000 times
问题描述
我需要帮助!我使用MFC和使用CRecordset类在C ++中编程。
我的问题是我在大量使用期间每秒使用Requery()函数大约10次。经过大约一个小时的大量使用后,Requery()函数停止工作;所有以前的Re-querys都有效,不再有效!大约15分钟后出现此错误,我的程序崩溃了。有没有人听说过这个问题?
在winXP(32位)和windows7(64位)中编译,结果相同。发现此错误发生在具有MS Access(2003)或SQL(2005)的5台以上的计算机中。唯一常见的是MSVS2005
多年前,我从微软获得了免费的MSVC2005副本,用于参加其中一个在线课程;它是Visual Studio 2005的全功能标准版。
有人有任何线索吗?
我有4个线程访问一个函数(问题函数),在那里它汇集到一个共享资源,即数据库。我使用信号量,以便一次性使用只读Requery。其中一个字段是CLongBinary,它在重新查询时保存一个要在屏幕上显示的图片信息。
对于下面的一些格式感到抱歉,粘贴但是出来不同并手动编辑以使其可读;希望
以下是一些代码片段。
ViewClass.cpp
要领:
<前lang =cpp> 如果(m_pCardSet-> IsOpen())
{
m_pCardSet-> m_MyParam = 1 ;
m_pCardSet-> m_nParams = 1 ;
m_pCardSet-> m_strCardNoParam = CardNo;
m_pCardSet-> m_strFilter = CardNo =?;
m_pCardSet-> Requery();
if (m_pCardSet-> IsEOF()&& m_pCardSet-> IsBOF())
{
p = CardDBQue .RemoveHead();
n = InterlockedDecrement(& CardDBCount);
return (_ T( NO ENTRIES IN CARDHOLDER DATABASE));
} // 只有一个记录会显示,没有重复
if (( int )m_pCardSet-> m_Image.m_dwDataLength< 100 )
HAS_PIX = FALSE;
else
HAS_PIX = TRUE;
if (HAS_PIX == TRUE)
if (CreateStreamOnHGlobal (NULL,TRUE,& pStream)== S_OK)
{
LPVOID buffer = GlobalLock(m_pCardSet-> m_Image.m_hData);
pStream->写入(缓冲区,(UINT)m_pCardSet-> m_Image.m_dwDataLength,ulWritten);
GlobalUnlock(m_pCardSet-> m_Image.m_hData);
}
.....等
m_pCardSet CLASS :(标准设置)
class CCardHolderSet: public CRecordset
{
public :
CCardHolderSet(CDatabase * pDatabase = NULL);
DECLARE_DYNAMIC(CCardHolderSet)
CDBpwd m_dbParam;
CStringA m_CardNo; // 卡号10位
BOOL m_AntiPass; // 是APB ACTIVE?
CStringA m_FirstName; // CardHolder名称(第一个)
CStringA m_LastName; // CardHolder姓氏
CStringA m_TransCode; // 不确定
CLongBinary m_Image; // 持卡人的照片
CStringA m_ImageName; // 图片名称
BOOL m_Voided; // 无效卡
CStringA m_SecLevel;
CStringA m_strCardNoParam;
int m_MyParam; // 可决定使用哪些参数
/// ///////以下PARAMS,NOT FIELDS //////////////
// 覆盖
// 向导生成的虚函数覆盖
public :
virtual CString GetDefaultConnect(); // 默认连接字符串
virtual CString GetDefaultSQL(); // Recordset的默认SQL
virtual void DoFieldExchange(CFieldExchange * pFX); // RFX支持
// 实现
#ifdef _DEBUG
virtual void AssertValid() const ;
virtual void 转储(CDumpContext& dc)常量跨度>;
#endif
};
IMPLEMENTAION上面的类:
CCardHolderSet :: CCardHolderSet(CDatabase * pdb)
:CRecordset(pdb)
{
m_CardNo = _T( );
m_AntiPass = 0 ;
m_LastName = _T( );
m_FirstName = _T( );
m_TransCode = _T( );
m_ImageName = _T( );
m_Image.m_hData = 0 ;
m_Voided = FALSE;
m_SecLevel = _T( );
m_nFields = 9 ;
m_nDefaultType = ConnectType;
m_strCardNoParam = _T( );
m_MyParam = 0 ;
m_nParams = 0 ;
}
CString CCardHolderSet :: GetDefaultConnect()
{
CString Dsn;
Dsn.Format( %s%s%s,m_dbParam.DbString,m_dbParam .DbParamStr,m_dbParam.DbLogonStr);
return (Dsn);
}
CString CCardHolderSet :: GetDefaultSQL()
{
if (CONNECT_SQL_DB == TRUE)
return _T( [dbo]。 [持卡人]跨度>);
else
return _T( [CardHolder]);
}
void CCardHolderSet :: DoFieldExchange(CFieldExchange * pFX)
{
pFX-> SetFieldType(CFieldExchange :: outputColumn);
RFX_Text(pFX,_T( [CardNo]),m_CardNo);
RFX_Bool(pFX,_T( [AntiPass]),m_AntiPass);
RFX_Text(pFX,_T( [FirstName]),m_FirstName);
RFX_Text(pFX,_T( [LastName]),m_LastName);
RFX_Text(pFX,_T( [TransCode]),m_TransCode);
RFX_Text(pFX,_T( [ImageName]),m_ImageName); // m_PixName);
RFX_LongBinary(pFX,_T( [Image]),m_Image);
RFX_Bool(pFX,_T( [Voided]),m_Voided);
RFX_Text(pFX,_T( [SecLevel]),m_SecLevel, 63999 跨度>);
switch (m_MyParam)
{
case 1 :
pFX-> SetFieldType(CFieldExchange :: param);
RFX_Text(pFX, CardNo,m_strCardNoParam);
break ;
默认:
break ;
}
}
Craig C.
您好,感谢您的回复,
我大部分时间都使用EOF && BOF,因为只有在没有结果的情况下它才会成立;空集。如果你查询一个不存在的值,你会发现它的工作原理只有&&而不是||
对代码很抱歉但是这个函数是唯一一个执行requery的函数。其他代码非常庞大,仅适用于此项目的100,000行。使用4个串行端口,13个线程,两个数据库中的22个表,8个存储过程,20个类。
时间,一次一个,但在交通繁忙时连续。这是卡片钥匙/电梯/报警器等的安全程序。我真的很想完成这个项目,因为它给了我一头白发!
使用Requery()拽掉RecordSet将无法正常工作。我原本希望它能一直对程序进行实时更新。解决方法是生成一个动态分配的结构,其中包含数据库的所有字段和内存中的所有行。如果远程用户更新了任何字段,则添加另一个表为TRUE / FALSE,这将更改为TRUE,然后实时重新加载整个结构而不会干扰正在运行的程序。它每10毫秒比Requery()(数据库)更快,内存不是现在的问题。
Requery()不是为了过度使用而构建的,它会失败。通过这个,我的意思是过度使用,每天24小时每10-50毫秒请求它...然后,你的高清失败
I need help! I program in C++ with MFC and using the CRecordset class.
My problem is I use the Requery() function about 10 times a second during heavy use. After about a hour of this heavy use, the Requery() function stops working; all of the previous Re-querys that worked, no longer works! After about 15 minutes of this error, my program crashes. Has anybody heard of this problem?
Compiled in winXP (32 bit) and windows7 (64bit) with the same results. This error is found to occur in more than 5 computers with MS Access (2003) or SQL (2005). The only thing common is the MSVS2005
I got a free copy of MSVC2005 from Microsoft for taking one of their online courses many years ago; it is a full featured standard edition of Visual Studio 2005.
Does anybody have any clues?
I have 4 threads accessing one function (the problem function) where it funnels down to a shared resource, the database. I use a semaphore so that the "read only" Requery is used one-at-time. One of the fields is a CLongBinary where it holds one picture info to be displayed on the screen when Re-queryied.
sorry about some of the format below, paste but came out different and hand edit to make it readable; hopefully
Below are some code snippets.
ViewClass.cpp
THE REQUERY:
if(m_pCardSet->IsOpen())
{
m_pCardSet->m_MyParam = 1;
m_pCardSet->m_nParams = 1;
m_pCardSet->m_strCardNoParam = CardNo;
m_pCardSet->m_strFilter = "CardNo = ?";
m_pCardSet->Requery();
if(m_pCardSet->IsEOF() && m_pCardSet->IsBOF())
{
p = CardDBQue.RemoveHead();
n = InterlockedDecrement(&CardDBCount);
return(_T("NO ENTRIES IN CARDHOLDER DATABASE"));
}//ONLY ONE RECORD WILL SHOW, NO DUPLICATES
if( (int)m_pCardSet->m_Image.m_dwDataLength < 100 )
HAS_PIX = FALSE;
else
HAS_PIX = TRUE;
if(HAS_PIX == TRUE)
if(CreateStreamOnHGlobal(NULL, TRUE, &pStream) == S_OK)
{
LPVOID buffer = GlobalLock(m_pCardSet->m_Image.m_hData);
pStream->Write(buffer, (UINT)m_pCardSet->m_Image.m_dwDataLength, ulWritten);
GlobalUnlock(m_pCardSet->m_Image.m_hData);
}
..... etc.
THE m_pCardSet CLASS: (Standard setup)
class CCardHolderSet : public CRecordset
{
public:
CCardHolderSet(CDatabase* pDatabase = NULL);
DECLARE_DYNAMIC(CCardHolderSet)
CDBpwd m_dbParam;
CStringA m_CardNo; //Card number 10 digits
BOOL m_AntiPass; //is APB ACTIVE?
CStringA m_FirstName; //CardHolder name (first)
CStringA m_LastName; //CardHolder last name
CStringA m_TransCode; //not sure
CLongBinary m_Image; //picture of cardholder
CStringA m_ImageName; //picture name
BOOL m_Voided; //voided cards
CStringA m_SecLevel;
CStringA m_strCardNoParam;
int m_MyParam; //varable to decide which params to use
////////// PARAMS BELOW,NOT FIELDS //////////////
// Overrides
// Wizard generated virtual function overrides
public:
virtual CString GetDefaultConnect(); // Default connection string
virtual CString GetDefaultSQL(); // default SQL for Recordset
virtual void DoFieldExchange(CFieldExchange* pFX); // RFX support
// Implementation
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
};
IMPLEMENTAION OF THE CLASS ABOVE:
CCardHolderSet::CCardHolderSet(CDatabase* pdb)
: CRecordset(pdb)
{
m_CardNo = _T("");
m_AntiPass = 0;
m_LastName = _T("");
m_FirstName = _T("");
m_TransCode = _T("");
m_ImageName = _T("");
m_Image.m_hData = 0;
m_Voided = FALSE;
m_SecLevel = _T("");
m_nFields = 9;
m_nDefaultType = ConnectType;
m_strCardNoParam = _T("");
m_MyParam = 0;
m_nParams = 0;
}
CString CCardHolderSet::GetDefaultConnect()
{
CString Dsn;
Dsn.Format("%s%s%s", m_dbParam.DbString,m_dbParam.DbParamStr, m_dbParam.DbLogonStr);
return(Dsn);
}
CString CCardHolderSet::GetDefaultSQL()
{
if(CONNECT_SQL_DB == TRUE)
return _T("[dbo].[CardHolder]");
else
return _T("[CardHolder]");
}
void CCardHolderSet::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, _T("[CardNo]"), m_CardNo);
RFX_Bool(pFX, _T("[AntiPass]"), m_AntiPass);
RFX_Text(pFX, _T("[FirstName]"), m_FirstName);
RFX_Text(pFX, _T("[LastName]"), m_LastName);
RFX_Text(pFX, _T("[TransCode]"), m_TransCode);
RFX_Text(pFX, _T("[ImageName]"), m_ImageName);//m_PixName);
RFX_LongBinary(pFX, _T("[Image]"), m_Image);
RFX_Bool(pFX, _T("[Voided]"), m_Voided);
RFX_Text(pFX, _T("[SecLevel]"), m_SecLevel, 63999);
switch(m_MyParam)
{
case 1:
pFX->SetFieldType(CFieldExchange::param);
RFX_Text(pFX, "CardNo", m_strCardNoParam);
break;
default:
break;
}
}
Craig C.
Hi and thanks for the reply,
I use the EOF && BOF most of the time because it will be true only if there no results; empty sets. If you requery on a non-existant value, you will find it works and only as "&&" and not " ||"
Sorry about the code but this function is the only one that does the requery. The other code(s) is massive, about 100,000 lines just for this project. Using 4 serial ports, 13 threads, 22 tables in either database, 8 stored procedures, 20 class's.
Timing, one at a time but continuous under heavy traffic. This is a security program for card keys/elevators/alarms etc. I would really like to finish this project because its giving me grey hair!
Slugging the RecordSet using Requery() will not work. I originally wanted it to have a live update on the program all the time. The workaround is making a dynamically allocated struct holding all the fields of the database and all the rows in memory. Added another table which is TRUE/FALSE if any of the fields were updated by a remote user, this would change to TRUE and then the whole struct would be re-loaded in real-time without disturbing the running program. Its faster than Requery() (ing) the database every 10 msec and memory isn't an issue nowadays.
Requery() is not built to be over-used, it will fail. By that, I mean over-used by requesting it every 10-50 msec for 24 hours a day...YOY then, your HD fails
这篇关于> 1000次后,Requery()失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!