Click here to Skip to main content
15,867,686 members
Please Sign up or sign in to vote.
2.52/5 (5 votes)
See more:
Please check the code below:
header file:
C++
#pragma once
#include "ColoredListCtrl.h"

// CChildView window

class CPhoneVerificationView : public CWnd
{
private:
	CColoredListCtrl m_Grid;
	CButton m_OpenFile,btn2_export_excel;
	CString m_sFileName;
	CEdit m_FilePathCtrl, m_FileLeft;
	INT UnderProcess, CantClose;
	CWinThread *m_cwt;
	CFileDialog *fOpenDlg, *PhoneList;
	wchar_t* pBuffer;
// Construction
public:
	CPhoneVerificationView();

// Attributes
public:

// Operations
public:

// Overrides
	protected:
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

// Implementation
public:
	virtual ~CPhoneVerificationView();
	void LoadCDR();
	static UINT StaticLoadCDR(LPVOID lp);
	// Generated message map functions
private:
	void LoadPhoneList();
	INT GetPhoneNumberRow(CString);
protected:
	afx_msg void OnPaint();
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnSize(UINT, int, int);
	afx_msg void SaveOnExcelThread();
	void CreateHeader();
	void GetFileName();
	void CreateThreadFor();

	
	
	DECLARE_MESSAGE_MAP()
};



C++
void CPhoneVerificationView::GetFileName()
{
	if(UnderProcess)	
	{
		MessageBox(L"One Process is running already");
		return;
	}
	PhoneList=new CFileDialog(TRUE);//, L"", L"", OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_ALLOWMULTISELECT, 
	//L"Text File (*.txt)|*.txt|*.dat|*.csv||", this);
	pBuffer = new wchar_t[24576];      // 24K
    memset(pBuffer,0, sizeof (pBuffer));

	//fOpenDlg->SetWindowText(L"Select the Phone List");
	PhoneList->m_ofn.lStructSize=sizeof OPENFILENAME;
	PhoneList->m_ofn.Flags |= OFN_HIDEREADONLY|OFN_FILEMUSTEXIST;//|OFN_ALLOWMULTISELECT; 
    PhoneList->m_ofn.lpstrFile = pBuffer;
	PhoneList->m_ofn.nMaxFile = 24576; 
	PhoneList->m_ofn.hwndOwner = this->GetSafeHwnd();
	PhoneList->m_ofn.lpstrFilter = L"CSV File (*.csv)|*.csv|Text File(*.txt)|*.txt|All Files (*.*)|*.*||";;
	PhoneList->m_ofn.nFilterIndex =1;
	PhoneList->m_ofn.lpstrFileTitle = NULL ;
	PhoneList->m_ofn.nMaxFileTitle = 0 ;
	PhoneList->m_ofn.lpstrInitialDir=NULL ;

	int ret=PhoneList->DoModal();
	ASSERT( ( ret != IDOK ) || ( ret != IDCANCEL ) );

	if(ret==IDCANCEL)
	{
		delete PhoneList;
		delete []pBuffer;
		return;
	}

	LoadPhoneList();
	delete PhoneList;  //no more use
	delete []pBuffer;  //no more use
	fOpenDlg=new CFileDialog(TRUE);//, L"", L"", OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_ALLOWMULTISELECT, 
	//L"Text File (*.txt)|*.txt|*.dat|*.csv||", this);
	pBuffer = new wchar_t[24576];      // 24K
    memset(pBuffer,0, sizeof (pBuffer));

	//fOpenDlg->SetWindowText(L"Select the Phone List");
	fOpenDlg->m_ofn.lStructSize=sizeof OPENFILENAME;
	fOpenDlg->m_ofn.Flags |= OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_ALLOWMULTISELECT; 
    fOpenDlg->m_ofn.lpstrFile = pBuffer;
	fOpenDlg->m_ofn.nMaxFile = 24576; 
	fOpenDlg->m_ofn.hwndOwner = this->GetSafeHwnd();
	fOpenDlg->m_ofn.lpstrFilter = L"CSV File (*.csv)|*.csv|Text File(*.txt)|*.txt|All Files (*.*)|*.*||";;
	fOpenDlg->m_ofn.nFilterIndex =1;
	fOpenDlg->m_ofn.lpstrFileTitle = NULL ;
	fOpenDlg->m_ofn.nMaxFileTitle = 0 ;
	fOpenDlg->m_ofn.lpstrInitialDir=NULL ;

	//int 
	ret=fOpenDlg->DoModal();
	ASSERT( ( ret != IDOK ) || ( ret != IDCANCEL ) );
	if(ret==IDOK)
	{
		CreateThreadFor();
	}
	else
	{
		delete []fOpenDlg->m_ofn.lpstrFile;
		delete fOpenDlg;
		fOpenDlg=NULL;
	}
}


void CPhoneVerificationView::CreateThreadFor()
{
	m_cwt=AfxBeginThread(StaticLoadCDR,this,THREAD_PRIORITY_NORMAL,0,0,NULL);
}

UINT CPhoneVerificationView::StaticLoadCDR(LPVOID lp)
{
	CPhoneVerificationView *proc=(CPhoneVerificationView *)lp;

	proc->LoadCDR();
	
	return 1;
}
void CPhoneVerificationView::LoadCDR()
{
	if(UnderProcess)
	{
		MessageBox(L"Once Process is running already");
		return;
	}
	UnderProcess=1;
	int i = 0;
	CString Today;
	time_t ti;
	memset(&ti, 0, sizeof time_t);
	time(&ti);   // get time now
	struct tm *now = localtime(&ti);
	Today.Format(L"%d-%0d-%0d", now->tm_year+1900, now->tm_mon+1, now->tm_mday);
	UnderProcess=1;
	CantClose=1;
	CMySQLEx conn;
	
	int count=0;
	int row_count = 0U;
	int FileCount=0;
	while(UnderProcess && FileCount+1<=m_FileList.size())
	{
		FileCount++;
		CString str,ret;
		str.Format(L"%d", FileCount);
		m_FileLeft.SetWindowText(str);
		m_sFileName=m_FileList[FileCount-1];
		const char field_terminator = '\t';
		const char line_terminator  = '\n';
		const char enclosure_char   = '"';
		csv_parser CDRParser(m_sFileName.GetBuffer());
		m_sFileName.ReleaseBuffer();
		CDRParser.SetSkipLine(0);
		CDRParser.SetEnclosedChar(enclosure_char);
		CDRParser.SetFieldTerminator(field_terminator);
		CDRParser.SetLineTerminator(line_terminator);
		CDRParser.SetEscapeChar('\\');
		
		/* Check to see if there are more records, then grab each row one at a time */
		CStringA Query;
		
		double TotalCharge=0;
		while(CDRParser.has_more_rows())
		{
			count++;
			struct RET_CSV *row;
			int ColumnCount;
			row = CDRParser.GetNextRow(&ColumnCount);
			if(ColumnCount==0)
				continue;

			if(strcmp("WillCom WVPN", row[3].Value)!=0)
				continue;
			
			int RowNumber=GetPhoneNumberRow(CFunctions::UTF8toUTF16(row[6].Value));
			if(RowNumber==-1)
				continue;
			str=m_Grid.GetItemText(RowNumber, 3);
			CString Date;
			Date.Format(L"%c%c%c%c-%c%c-%c%c", row[0].Value[0],row[0].Value[1],row[0].Value[2],row[0].Value[3],row[0].Value[4],row[0].Value[5],row[0].Value[6],row[0].Value[7]);
			int cmp=wcscmp(Date,str.GetBuffer());//str.Compare(Date);
			str.ReleaseBuffer();
			if(cmp<=0)
				continue;
			m_Grid.SetItemText(RowNumber, 3, Date);
			str=CFunctions::UTF8toUTF16(row[1].Value);
			m_Grid.SetItemText(RowNumber, 4, str);

			
			long notused=CFunctions::DateDifferenct(Today, Date);
			str.Format(L"%ld", notused);
			
			m_Grid.SetItemText(RowNumber, 6, str);
		}
	}

	UnderProcess=0;
//	delete []PhoneList->m_ofn.lpstrCustomFilter;
//	delete PhoneList;
	
	MessageBox(L"Process is Done");
	m_cwt->m_bAutoDelete = TRUE;
	AfxEndThread(0);
}


The problem is after I close the application it is not quieting. It keeps running.

Here is some information that I saw in task manager.

TimeNumber of thread
Before I start the process6
After I start the process(at the beginning)12
After I start the process(after some time)8
After The process is done7


So, What I see at the end one process is still running. Even if I close the window still there is one thread running, can you suggest what shall i do to figure out which is running?
Posted
Updated 18-Apr-13 22:17pm
v6
Comments
Leo Chapiro 17-Apr-13 4:25am    
Obviously one of the worker threads you have created is running after the main thread is gone, I suppose it is the m_cwt. Can you check it? What is if you don't start this thread? Is then the issue gone?
Coder Block 17-Apr-13 5:08am    
its not solution but you can try
exit(0).
To forcefully stop process and tread.
[no name] 17-Apr-13 5:26am    
No, It wont help.
Coder Block 17-Apr-13 5:31am    
have u try it..
in exitInstance()
Malli_S 19-Apr-13 3:38am    
Could you please post the complete CPhoneVerificationView::LoadCDR()? It seems that this function is not exiting or might be creating another thread.

It would be helpful to see your header. I can only assume that your member function that handles the thread proc is declared static. I think there is a problem with calling conventions. The code expects a function with _cdecl calling conventions and you are likely giving it the C++ conventions. This may not be a problem but it is bad form.

Secondly, as a worker thread you should probably create the thread as suspended and set the m_bAutoDelete to TRUE. In your code it would be m_cwt->m_bAutoDelete = TRUE; Finally to end this kind of thread, follow the directions of MSDN

Quote:
To end the thread, call AfxEndThread from within the thread, or return from the controlling function of the worker thread.


Looking at your design, I gotta ask why are you using threads. You are accessing your 'this' pointer in an unsafe way from a worker thread. If you have multiple threads created they could all be jacking with the member data of your class in the main thread.

Your design is prone to fail and grow exponentially complicated.

A MFC MDI document/view architecture is much better suited for your design. Imagine each one of your threads as a document/view pair. The main information can be stored in your CWinApp derived class.

I'm not trying to be hard on you but if you really want to do threads then derive a class from CWinThread and communicate to it with PostThreadMessage. I have a multithreaded MFC MDI document/view article that really explains how to derive threads and use them. You should look over that portion of my article and do some code copy/pasting in a scratch app to get an idea about making and using threads.
 
Share this answer
 
Comments
[no name] 18-Apr-13 23:56pm    
Thank you for your reply.
I added header, if you want to check.

I will follow the suggestion about

AfxEndThread

m_cwt->m_bAutoDelete = TRUE;

About my design pattern: I got it on searching online, may be I didn't follow it properly. I would request you, if you have time then please suggest me some link to follow, I will also search on google. If no time, no worry.

I used frame/view pair. I didn't use document/view pair. The reason I didnt use document/view architecture is I am not good at it, I had multiple view with various tasks and I don't know how to use more than one document/view architecture.

Once again, thank you for your time.
[no name] 19-Apr-13 0:35am    
I also have pasted the full void CPhoneVerificationView::GetFileName(), here I called two CFileDialog::model.

I am wondering if they are making any mess
Malli_S 19-Apr-13 5:32am    
From where GetFileName() is getting called? I don't see any call from worker thread.
[no name] 19-Apr-13 5:58am    
It is getting called on button click event
Finally I have figured out the way,

The problem:

Actually the info I didn't share(didn't realize it can be important) was I was checking in debug mode. Then I realize that if the csv file is small the program quit but if the csv file is big,10 mb, the program does not quit.

And I also notice that memory usage was increasing rapidly. Then I wrote a small debug code to store all allocation in a linked list including file name, variable name and the line number.
18862040, 220, e:\ryo desktop\ryo desktop\csv\csv_parser.cpp, buff
18730496, 220, e:\ryo desktop\ryo desktop\csv\csv_parser.cpp, buff
18729816, 220, e:\ryo desktop\ryo desktop\csv\csv_parser.cpp, buff
18808512, 220, e:\ryo desktop\ryo desktop\csv\csv_parser.cpp, buff
18802840, 220, e:\ryo desktop\ryo desktop\csv\csv_parser.cpp, buff
18729880, 220, e:\ryo desktop\ryo desktop\csv\csv_parser.cpp, buff
18802904, 220, e:\ryo desktop\ryo desktop\csv\csv_parser.cpp, buff
18735864, 220, e:\ryo desktop\ryo desktop\csv\csv_parser.cpp, buff


through this, I figured out that one of my dynamic variable is not freeing at all, I figured out the cause and fixed it. now, Its working fine :) Thank you everybody for your support
 
Share this answer
 
proc->LoadCDR(); does something what doesnt end. You need an abortion signal / event.

I wpuld use SetEvent() - API.
 
Share this answer
 
Comments
[no name] 17-Apr-13 5:08am    
Hi,
Thank you for your message, the function reach to its last statement I checked, do you mean it still keep running. how?
KarstenK 17-Apr-13 5:20am    
is the thread StaticLoadCDR exited?

It can be that some deconstructor are hanging. (It is bad style to have workload in a dtor)

But I dont know the code. Make some output to the console to find the point of the non-exit.
[no name] 17-Apr-13 5:25am    
The three function I showed here, all of them exit properly, How I know- I prompt a message right before return; I see all of those message
KarstenK 17-Apr-13 6:11am    
use the TRACE macro or like that:

cout << "Hello World" << endl;
[no name] 17-Apr-13 6:20am    
ok, i will check

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900