关于CPU窗口的自动弹出(一波三折,恼人啊!) (200分)

  • 主题发起人 主题发起人 Sachow
  • 开始时间 开始时间
S

Sachow

Unregistered / Unconfirmed
GUEST, unregistred user!
CPU窗口有时会自动弹出,但通常是在程序有问题的时候才弹出,下面是CB帮助中关于CPU窗口自动弹出的解释:
The CPU window opens automatically whenever program execution stops at a location for which source code is unavailable.
我的最近一个COM+项目中,在我调用了最后添加的两个方法后,在IDE调试状态下,当组件的引用计数为零,并到达闲置关闭时间,需要释放时,就会弹自动出CPU窗口(在进入调试前如果按的不是F9,而是F7或F8,同样要出CPU窗口。
令我不解的是,弹出CPU窗口是有一定规律的:我的组件共有23个方法,调用前21个方法,关闭时都不会出CPU窗口,而调用后两个就会出,而且后两个中也是要进入到某几个条件时,关闭时才出弹出CPU窗口。这就令我很烦恼了,我的代码里完全没有直接的会导致访问内存错误的处理,只用了Format()和AnsiString::sprintf()来格式化字符串,格式化后的结构用WideString(AnsiString变量).Detach()的方式处理返回值,这都是很常用的方式,怎么会导致CPU窗口的弹出呢?
 
运行的代码没有源代码呀,你的后两个是调用了什么?
 
全部代码都是自己写的,没有调用任何其它的动态库和控件包。出CPU窗口的是业务逻辑组件,通过TDCOMConnection连接数据库组件。
下面是程序的框架,需要补充说明的是程序运行结果完全正常,就是关闭组件时会出CPU窗口。
STDMETHODIMP TiPAS_WebSvrImpl::GetNbrInformation(BSTR PhoneNbr,
BSTR* Result)
//获取号码信息
{
TClientDataSet *cds;
if (CompareText(PhoneNbr, "")==0){
*Result = WideString("错误:号码不能为空!").Detach();
return S_FALSE;
}
cds = m_DataModule->CDS1;
try{
....
cds->Open();
if (cds->Eof){
*Result = WideString(Format("号码“%s”不存在",
ARRAYOFCONST((PhoneNbr)))).Detach();
}else
{
//检查号码是否可用
if (CompareText(cds->FieldByName("syzt")->AsString, "A")==0)
{
//号码可用
cds->Close();
cds->CommandText = ...
cds->Open();
if (cds->Eof)
*Result = WideString(Format("号码“%s”可用,未出库",
ARRAYOFCONST((PhoneNbr)))).Detach();
else
*Result = WideString(Format("号码“%s”可用,被分配给“%s”,出库日期:%s",
ARRAYOFCONST((PhoneNbr,
cds->Fields->Fields[2]->AsString,
DateToStr(cds->Fields->Fields[1]->AsDateTime))))).Detach();
}else
{ //号码已被占用
//检查号码的去向
cds->Close();
cds->CommandText = ...
cds->Params->ParamByName("aNbr")->AsString = PhoneNbr;
cds->Open();
if (!cds->Eof){
TStringList *sl = new TStringList;
AnsiString S;
try{
sl->Add(Format("电话号码“%s”已被占用,营业受理记录如下:<p>",
ARRAYOFCONST((PhoneNbr))));
m_DataModule->DataSetTableProducer1->DataSet = cds;
S = m_DataModule->DataSetTableProducer1->Content();
sl->Add(S);
sl->Add("</p>");
//列出电话号码的历史营业受理记录
*Result = WideString(sl->Text).Detach();
}__finally{
delete sl;
}
}else
*Result = WideString(Format("号码“%s”已被占用%s",
ARRAYOFCONST((PhoneNbr, "(未能获取其营业信息)")))).Detach();
}
}
cds->Close();
}catch(Exception &amp;E){
return Error(WideString(E.Message), IID_IiPAS_WebSvr);
}
return S_OK;
}
//---------------------------------------------------------------------------
 
找不到源碼吧。
 
今天下午终于把它解决了,感觉只能用一个词形容:闹鬼!
在试了万般无奈的情况下,我把逻辑结构这样改了一下:
STDMETHODIMP TiPAS_WebSvrImpl::GetNbrInformation(BSTR PhoneNbr,
BSTR* Result)
{
TClientDataSet *cds;
...
try{
....
cds->Open();
if (cds->Eof){
*Result = WideString(Format("号码“%s”不存在",
ARRAYOFCONST((PhoneNbr)))).Detach();
return S_OK;
}
//------------------------ 这里有一点差别 ------------------------//
if (cds->FieldByName("syzt")->AsString == "A")
{
if (cds->Eof){
...
}else
{
...
}
}else
{
cds->Close();
cds->CommandText = ...
cds->Params->ParamByName("aNbr")->AsString = PhoneNbr;
cds->Open();
if (!cds->Eof){
//---------------------- 原来的问题出在执行到这个条件以后 ------------------//
...
}else
{
...
}
}
cds->Close();
}catch(Exception &amp;E){
return ..
}
return S_OK;
}
问题就解决了,真是可怕啊,遇到这样的怪问题,即使解决了也没有任何有价值的经验,下次再遇到的时候还可能手足无措!
希望大家谈谈类似的经历,综合起来,就会变成有价值的信息。
 
我经常遇到这样的问题,综合原因,有以下几条:
1。内存泄漏
2。逻辑指针出错
3。没有找到需要的资源
4。异常
以上是我的一些拙见,请各位朋友提出更多更有力的原因,谢谢!
感谢搂主Sachow的问题!
 
原以为已经解决,但今天下午又再次遇到了这种问题,是不是编辑器或高度器的故障啊?!
下面两个方法,执行前一个的时候就,在返回以后就会弹出CPU窗口,但后一个就不会。
STDMETHODIMP TiPAS_AppSvrProxyImpl::AddMIDRange(BSTR RetailerID,
BSTR begin
Nbr, BSTR EndNbr, BSTR PResource, BSTR PhoneModel,
DATE AllocTime, int* Result)
{
IDispatch* disp = (IDispatch*)(m_DataModule->SConn->AppServer);
IiPAS_AppServerDisp Intf((IiPAS_AppServer*)disp);
Intf.AddMIDRange(RetailerID, begin
Nbr, EndNbr, PResource, PhoneModel,
AllocTime, Result);
return S_OK;
}
//---------------------------------------------------------------------------
STDMETHODIMP TiPAS_AppSvrProxyImpl::AddNbrRange(BSTR RetailerID,
BSTR begin
Nbr, BSTR EndNbr, DATE AllocTime, int* Result)
{
IDispatch* disp = (IDispatch*)(m_DataModule->SConn->AppServer);
IiPAS_AppServerDisp Intf((IiPAS_AppServer*)disp);
Intf.AddNbrRange(RetailerID, begin
Nbr, EndNbr, AllocTime, Result);
return S_OK;
}
//---------------------------------------------------------------------------
这两个方法调用的是另一台服务器上另一个组件的同名方法,由于两台机器之间要设防火墙,且CIS(COM Internet Service)不支持MTS/COM+的回调,只好在这边用TSocketConnection连接防火墙后面的应用服务器,然后做个调用代理,其中IiPAS_AppSvrProxy所有的方法定义与IiPAS_AppServer的定义是完全相同的,IDL都是从那里粘贴过来的,但这一粘贴,问题就出现了,几乎完全相同的两个方法,一个就要出CPU窗口,另一个却不出!(在IiPAS_AppServer的代码实现中,两个方法的代码也几乎是一模一样的,而且在本机上调用IiPAS_AppServer的这两个办法时也是完全正常的)
苦恼啊!这要不是编译器或调试器的问题,又会是什么问题呢?
 
我以前使用2000下delphi也有这个毛病,后来再2000server下面又装了一个delphi,同样的工程没有一点问题!!见鬼
 
我遇到这个问题都是对同一个控件控制上冲突,呵呵
 
P4電腦編譯過的程式到P3電腦上再用會有這種情況
 
多人接受答案了。
 
后退
顶部