> 1000次后,Requery()失败 [英] Requery() fails after >1000 times

查看:76
本文介绍了> 1000次后,Requery()失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要帮助!我使用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


这篇关于&gt; 1000次后,Requery()失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆