线程无故退出

wjx_0_2001 2009-12-29 04:34:35
背景:一个程序(基于DLG)通过调用第三方提供的接口,进行读卡


附注:这个程序时通过两个COM口,来读卡的,两个COM口是轮换着读卡(不管当前有没有在读卡或者出现异常)


问题:在这个程序启动后,有时候不读卡,但是,程序时通过一个线程,循环(死循环)读卡的,如果读到卡,就在DLG界面

上显示

==============================================================================================================
实在找不问题在哪儿,只好在程序中加入日志,希望能通过日志发现问题

流程如下:

void lpRecvProc(LPVOID lpParam)
{
// 取得窗口指针
CMyCardDlg* pDlg=(CMyCardDlg*)lpParam;

// 初始化接口

// 初始化刷卡机端口
long ret = iniCom( pDlg->m_nCom);
long ret2=iniCom(pDlg->m_nCom2);

if(ret != 0||ret2!=0)
{
AfxMessageBox("端口初始化失败!");
return ;
}


bool bIsBusy=false;//false 表示当前没有处理卡信息,true 表示正在处理卡信息

bool bIsflag=false;//false 表示通过COM1口读卡,true 表示通过COM2口读卡


// 开始循环读卡
while(true)
{
if(bIsBusy==true)
{
WriteLog(正在处理卡信息);
continue;
}

// 取得用户卡信息
//if(bIsflag==false)
{
::WriteLog(com1读卡前);//表示当前用com1读卡,但是还没读 //
ret = readCard(com1,...)//通过接口读卡
//
::WriteLog(com1读卡后);//表示当前用com1读卡,已经读完卡
//
}
else
{
::WriteLog(com2读卡前);//表示当前用com2读卡,但是还没读 //
ret = readCard(com2,...)//通过接口读卡
//
::WriteLog(com2读卡后);//表示当前用com2读卡,已经读完卡

}

bIsBusy = true;

switch( ret)
{
case 0:// 成功
break;
case 1:// 无卡
case 2://
default:// 异常返回值
bIsBusy=false;
bIsflag=!bIsflag;
WriteLog(无卡);//
continue;
}

pDlg->SendMessage( WM_USER+2 );数据打包,请求服务处理

数据解析,将服务处理的结果值赋予ret

switch ( ret )
{
case 0:
显示刷卡成功
break;
case 1:
显示扣款成功
break;
default:
显示操作失败
break;
}

bIsBusy=false;
bIsflag=!bIsflag;
continue;

}
WriteLog(线程退出);
return;

}

==========================================
有点多,呵


再次出现这个问题时,程序执行到标记为红处后,就停止了,因为这个时候日志没有变化了


既在WriteLog(com1读卡前);//或者WriteLog(com2读卡前);//执行后,


线程就没有在循环工作了


-----------------------------
但这个是死循环,没有理由退出

望各位给给意见

多谢先了

...全文
440 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
wjx_0_2001 2010-01-11
  • 打赏
  • 举报
回复
呵呵

其实只要看我最开始贴的就行,那我简约点贴
void lpRecvProc(LPVOID lpParam)
{
// 取得窗口指针
CMyCardDlg* pDlg=(CMyCardDlg*)lpParam;

// 初始化接口

// 初始化刷卡机端口
long ret = iniCom( pDlg->m_nCom);
long ret2=iniCom(pDlg->m_nCom2);

if(ret != 0||ret2!=0)
{
AfxMessageBox("端口初始化失败!");
return ;
}


bool bIsBusy=false;//false 表示当前没有处理卡信息,true 表示正在处理卡信息

bool bIsflag=false;//false 表示通过COM1口读卡,true 表示通过COM2口读卡


// 开始循环读卡
while(true)
{
if(bIsBusy==true)
{
WriteLog(正在处理卡信息);
continue;
}
try
{
// 取得用户卡信息
if(bIsflag==false)
{
::WriteLog(com1读卡前);//表示当前用com1读卡,但是还没读 //
ret = readCard(com1,...)//通过接口读卡
::WriteLog(com1读卡后);//表示当前用com1读卡,已经读完卡

}
else
{
::WriteLog(com2读卡前);//表示当前用com2读卡,但是还没读 //
ret = readCard(com2,...)//通过接口读卡
::WriteLog(com2读卡后);//表示当前用com2读卡,已经读完卡

}
}
catch(...)
{
::WriteLog(异常);//
}

bIsBusy = true;

switch( ret)
{
case 0:// 成功
break;
case 1:// 无卡
case 2://
default:// 异常返回值
bIsBusy=false;
bIsflag=!bIsflag;
WriteLog(无卡);//
continue;
}
…………
///

附注:
红色标记的,为执行这行代码后,就不在往下执行了,WriteLog是后来加上的,所以,肯定不会是这个出问题

lllyyy2403 2010-01-11
  • 打赏
  • 举报
回复
兄弟,这代码也太长了点哈,建议先用MessageBox查查情况,然后针对一小段代码提问效果会更好。
wjx_0_2001 2010-01-11
  • 打赏
  • 举报
回复
没贴好
luan
wjx_0_2001 2010-01-11
  • 打赏
  • 举报
回复
void lpRecvProc(LPVOID lpParam)
{
// 取得窗口指针
CMyCardDlg* pDlg=(CMyCardDlg*)lpParam;

// 初始化接口
HINSTANCE mlib;
IniCom iniCom;
CloseCom closeCom;
ReadCard readCard;
DecCard decCard;

int Money;//单位分
mlib = LoadLibrary("connectv23.dll");



if(mlib != NULL)
{
iniCom = (IniCom)GetProcAddress(mlib , "Connect");
closeCom = (CloseCom)GetProcAddress(mlib , "Disconnect");
readCard = (ReadCard)GetProcAddress(mlib , "ReadCardInfo");
decCard = (DecCard)GetProcAddress(mlib , "DecCardMoney");
}
else
{
AfxMessageBox("加载动态库失败,请重新启动程序!");
return;
}

if(iniCom==NULL||closeCom==NULL||readCard==NULL||decCard==NULL)
{
AfxMessageBox("加载动态库失败,请重新启动程序!");
return;
}

// 初始化刷卡机端口
long ret = iniCom( pDlg->m_nCom);
long ret2=iniCom(pDlg->m_nCom2);

if(ret != 0||ret2!=0)
{
AfxMessageBox("端口初始化失败!");
return ;
}

CString strcardno;
int npos=-1;

CString strError="";

CString strLog="";//

//unsigned char ucShowCardNo[256],ucName[256],ucCardNo[256],ucMoney[256];
//unsigned char ucDeCardNo[3];

bool bIsBusy=false;

bool bIsflag=false;

CTime time

DWORD dwError;

// 开始循环读卡
while(true)
{

unsigned char ucShowCardNo[256],ucName[256],ucCardNo[256],ucMoney[256];
unsigned char ucDeCardNo[3];
memset(ucShowCardNo,0x00,sizeof(ucShowCardNo));
memset(ucCardNo,0x00,sizeof(ucCardNo));
memset(ucName,0x00,sizeof(ucName));
memset(ucMoney,0x00,sizeof(ucMoney));

pDlg->m_FlagBmp.DeleteObject();

try
{ // 取得用户卡信息
if(bIsflag==false)
{

::WriteLog("com1前");//每次在这里执行完后,就停止了,可能执行了,但导致异常


ret = readCard(pDlg->m_nCom,
ucShowCardNo
ucName,
ucCardNo,
ucMoney
);
::WriteLog("com1后");
}
else
{
::WriteLog("com2前");//每次在这里执行完后停止了,后面就不在执行,可能执行了,但导致异常

ret = readCard(pDlg->m_nCom2,
ucShowCardNo,
ucName,
ucCardNo,
ucMoney
);
::WriteLog("com2后");
}
}
catch(...)
{
::WriteLog("线程异常");
}


bIsBusy = true;

switch( ret)
{
case 0:// 成功
break;
case 1:// 无卡

pDlg->m_usrstatus.Format("无卡!");
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR);
pDlg->m_sBitmap.SetBitmap(pDlg->m_FlagBmp);
pDlg->SendMessage( WM_USER+1);//更新显示
bIsBusy=false;
bIsflag=!bIsflag;
::WriteLog("无卡");
Sleep(100);
continue;
case 2:// 非系统发行卡
pDlg->m_usrstatus.Format("非系统发行卡!");
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );
pDlg->SendMessage( WM_USER+1 );
Sleep(pDlg->m_lRTime);
bIsBusy=false;
bIsflag=!bIsflag;
continue;
case 3://挂失卡
pDlg->m_usrstatus.Format("挂失卡!");
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );
pDlg->SendMessage( WM_USER+1 );
Sleep(pDlg->m_lRTime);
bIsBusy=false;
bIsflag=!bIsflag;
continue;
case 4:// 已过有效期
pDlg->m_usrstatus.Format("该卡已过有效期!");
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );
pDlg->SendMessage( WM_USER+1 );
Sleep(pDlg->m_lRTime);
bIsBusy=false;
bIsflag=!bIsflag;
continue;
case 5://卡类使用不允许
pDlg->m_usrstatus.Format("卡类使用不允许!");
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );
pDlg->SendMessage( WM_USER+1 );
Sleep(pDlg->m_lRTime);
bIsBusy=false;
bIsflag=!bIsflag;
continue;
case 6://感应头通信失败
pDlg->m_usrstatus.Format("感应头通信失败!");
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );
pDlg->SendMessage( WM_USER+1 );
Sleep(pDlg->m_lRTime);
bIsBusy=false;
bIsflag=!bIsflag;
continue;
case 8://中途拔卡
pDlg->m_usrstatus.Format("中途拔卡!");
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );
pDlg->SendMessage( WM_USER+1 );
Sleep(pDlg->m_lRTime);
bIsBusy=false;
bIsflag=!bIsflag;
continue;
case 9://金额不足
pDlg->m_usrstatus.Format("金额不足!");
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );
pDlg->SendMessage( WM_USER+1 );
Sleep(pDlg->m_lRTime);
bIsBusy=false;
bIsflag=!bIsflag;
continue;
case -6://与POS通信超时
pDlg->m_usrstatus.Format("通信超时!");
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );
pDlg->SendMessage( WM_USER+1 );
Sleep(pDlg->m_lRTime);
bIsBusy=false;
bIsflag=!bIsflag;
continue;
default:// 异常返回值
pDlg->m_usrstatus.Format("接口读卡异常!");//1210
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );
pDlg->SendMessage( WM_USER+1 );
Sleep(pDlg->m_lRTime);
bIsBusy=false;
bIsflag=!bIsflag;
WriteLog("接口异常");//
continue;
}
//
npos=-1;//
strcardno="";
strcardno=ucShowCardNo;
npos=strcardno.Find(" ");
strcardno=strcardno.Left(npos);
pDlg->m_cardID =strcardno ;
pDlg->m_cardID.TrimLeft();
pDlg->m_cardID.TrimRight();

Money=::GetIntMoney(ucMoney);//money);

// 数据打包

pDlg->m_pPack = (PACKAGE*)pDlg->m_buf;
memset(pDlg->m_pPack->number , 0 , 80);
memset(pDlg->m_pPack->returnInfo , 0 ,80);
memset(pDlg->m_pPack->groupName , 0 , 80);
memset(pDlg->m_pPack->loginName , 0 , 80);
memset(pDlg->m_pPack->userName , 0 , 80);
pDlg->m_pPack->type =2;
strcpy(pDlg->m_pPack->number, pDlg->m_cardID) ;
pDlg->m_pPack->roomid = pDlg->m_nID;
pDlg->m_pPack->money = Money;

// 请求服务处理
pDlg->SendMessage( WM_USER+2 );//服务处理

CString strBalance;
CString test ="wrong!";
int leftMoney =0;//
leftMoney= pDlg->m_pPack->money;//
ret = pDlg->m_pPack->type;
int cost=0;
cost = Money - leftMoney;

switch ( ret )
{
case 0:
pDlg->m_usrstatus="读卡成功";
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_UP);
pDlg->m_sBitmap.SetBitmap(pDlg->m_FlagBmp);
break;
case 1:
pDlg->m_usrstatus="扣款成功";
// 扣款
if(cost>0.00)
{
memset(ucDeCardNo,0x00,sizeof(ucDeCardNo));
ucDeCardNo[0] = ucCardNo[0];
ucDeCardNo[1] = ucCardNo[1];
ucDeCardNo[2] = ucCardNo[2];

if(bIsflag==false)
{
ret = decCard(pDlg->m_nCom , ucDeCardNo , cost );
}
else
{
ret = decCard(pDlg->m_nCom2 , ucDeCardNo , cost );//cardID
}
}
else
{
ret=0;
}


if( ret == 0 )
{
// 扣款成功
pDlg->m_pPack->type = 20; //
pDlg->m_pPack->money = Money;//;
pDlg->SendMessage( WM_USER+2);
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_DOWN );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );

WriteLog("扣款成功");//

}
else if(ret==9)
{
pDlg->m_usrstatus.Format("金额不足!");
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );
WriteLog("金额不足");//
}
else
{
pDlg->m_usrstatus.Format("失败 %d:%d" , ret , leftMoney);
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );
WriteLog("失败");//
}
break;
default:
pDlg->m_usrstatus="操作失败";
pDlg->m_FlagBmp.LoadBitmap(IDB_BITMAP_ERROR );
pDlg->m_sBitmap.SetBitmap( pDlg->m_FlagBmp );
WriteLog("操作失败");
break;
}

pDlg->m_strLoginName = pDlg->m_pPack->loginName;
pDlg->m_strUserName= pDlg->m_pPack->userName;
pDlg->m_money=pDlg->m_pPack->returnInfo;
pDlg->m_money += strBalance;
pDlg->m_classname = pDlg->m_pPack->groupName ;

pDlg->m_cardID = "";
pDlg->SendMessage( WM_USER+1);
Sleep(1000);

pDlg->m_strLoginName ="";
pDlg->m_strUserName="";
pDlg->m_money="";
pDlg->m_money += strBalance;
pDlg->m_classname ="" ;

pDlg->m_cardID = "";
pDlg->SendMessage( WM_USER+1);
//pDlg->m_bBusy = FALSE;
bIsBusy=false;
bIsflag=!bIsflag;
continue;//

}
closeCom(pDlg->m_nCom);
closeCom(pDlg->m_nCom2);
FreeLibrary(mlib);
return;

}
zhangrenhui 2010-01-11
  • 打赏
  • 举报
回复
ding
心留 2010-01-11
  • 打赏
  • 举报
回复
可以用vc调试一下,
或者在自己认为有可能出现错误的地方
messageBox()一下判断一下在哪句出的问题。
wolffan3150 2010-01-11
  • 打赏
  • 举报
回复
多半是readCard(com2,...)的问题,
可能用的方式有点不对,
要不就是readCard(com2,...)本身
就有bug,

建议注释掉readCard(com2,...),
测试下线程,
如果没问题就是readCard(com2,...)的问题了
sandyandy 2010-01-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 mazm_yanzhu 的回复:]
单步调试,最好的手段,代码也很短,应该很快就找到了
[/Quote]

yes
red-fly 2010-01-11
  • 打赏
  • 举报
回复
是不是红色那一行把程序塞住了?
wjx_0_2001 2010-01-11
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 ziplj 的回复:]
try catch(...)
一般线程自动退出时有异常发生的 

[/Quote]

加了,但是根本就没有执行到CATCH里面


我放源代码
wjx_0_2001 2010-01-11
  • 打赏
  • 举报
回复
还有个现象:

在用户现场,就出问题,但是在公司就不出问题(为了便于找出问题,专门讲用户现场用的机器弄到公司)

………………
wjx_0_2001 2010-01-11
  • 打赏
  • 举报
回复
vc 6.0中怎么没看到这个在哪儿设置?

不会么有吧
cnzdgs 2010-01-11
  • 打赏
  • 举报
回复
用try...catch时项目是否设置了启用SEH异常(/EHa)?
wjx_0_2001 2010-01-06
  • 打赏
  • 举报
回复
继续

别沉底啊

各位
ziplj 2010-01-06
  • 打赏
  • 举报
回复
try catch(...)
一般线程自动退出时有异常发生的
cnzdgs 2010-01-06
  • 打赏
  • 举报
回复
我前面说的放在try{}里面捕获异常,试过了吗?你没回应我也没法继续。
wjx_0_2001 2009-12-30
  • 打赏
  • 举报
回复
肯定是进入了while中,不然不会一直写日志的。更不可能读卡了

wjx_0_2001 2009-12-30
  • 打赏
  • 举报
回复
因为这个现象,不是很有规律的出现,有可能一天都没问题

有可能,刚开程序,就读不出卡来

也可能,刚执行一会,才出问题

所以,你根本不知道它什么时候会出现
===========================
我在公司将程序以调试状态执行,当出问题后,我在死循环中加断点,没有反应


所以就如CNZDGS说的那样,可能线程已经异常退出
bragi523 2009-12-30
  • 打赏
  • 举报
回复
那你单步的时候到底有没有进到while里面啊?
wjx_0_2001 2009-12-30
  • 打赏
  • 举报
回复
不是,因为从日志来看,这块就没执行
加载更多回复(7)

15,467

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧