Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: VC8.0
I have developed a screenshot application in VC++ 2005. It will take screenshots and save it in the server MYSQL database. The process is that, initially the file will be saving in C: drive, then after taking the blob data, the file will be removed. But it has been installed almost all system in my office. The problem is that, it takes more than 65% CPU usage. How to avoid this. Please help me. AFX_ODBC_CALL(::SQLExecute(m hstmt) takes too long......
void gdiscreen()
{
	using namespace Gdiplus;
	GdiplusStartupInput gdiplusStartupInput;
	ULONG_PTR gdiplusToken;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
	int c=0;
	HDC scrdc, memdc;
	HBITMAP membit;
	HBITMAP hOldBitmap;
	CString lpfilename;
	char buffer[1000];	   
	
	for(;;)
	{		
		scrdc = ::GetDC(0);
		int Height = GetSystemMetrics(SM_CYSCREEN);
		int Width = GetSystemMetrics(SM_CXSCREEN);
		memdc = CreateCompatibleDC(scrdc);
		membit = CreateCompatibleBitmap(scrdc, Width, Height);
		hOldBitmap=(HBITMAP) SelectObject(memdc, membit);
		BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);
		//Gdiplus::Bitmap bitmap(membit, NULL);
		Gdiplus::Bitmap* bitmap =  ::new Bitmap(membit, NULL );
 
		CLSID clsid;
		GetEncoderClsid(L"image/jpeg", &clsid);
		sprintf_s(buffer,"C:\\Program Files\\image%u.jpeg",c);		
		lpfilename=buffer;				
		bitmap->Save(lpfilename, &clsid); 
		IStream* tmpbuf = NULL;
		CreateStreamOnHGlobal(NULL, true, &tmpbuf);
		bitmap->Save(tmpbuf, &clsid);
		HGLOBAL hg = NULL;
		HRESULT  hr = GetHGlobalFromStream(tmpbuf, &hg);
		SIZE_T uSize = GlobalSize(hg);
		//GlobalUnlock(hg);
		
 
		int len=(int)uSize;  
		CFile file;
		BYTE buf[150];
		CStringA charstr(lpfilename);
		CString strblob;
	   const char *szSingle;
       szSingle=((const char *) charstr);	
 
		CString strDateTime;
	   SYSTEMTIME datetimenew;
			::GetLocalTime(&datetimenew);
			strDateTime.Format(_T("%02i-%02i-%02i %d:%d:%d"),
								datetimenew.wYear,
								datetimenew.wMonth,     
								datetimenew.wDay,       
								datetimenew.wHour,
								datetimenew.wMinute,
								datetimenew.wSecond);
		
		CdbImages       dbImages(&theApp.m_DB);
 
		dbImages.Open();
        dbImages.AddNew();
 
        CFile		fileImage;
        CFileStatus	fileStatus;
 
        fileImage.Open(lpfilename, CFile::modeRead);
        fileImage.GetStatus(fileStatus);
 
		dbImages.m_dateTime = strDateTime;
        //dbImages.m_BLOBName = fileImage.GetFileTitle();		
		dbImages.m_BLOBName = SqlStr3;
		
        dbImages.m_BLOBImage.m_dwDataLength = fileStatus.m_size;
 
        HGLOBAL hGlobal		= GlobalAlloc(GPTR,fileStatus.m_size);
        dbImages.m_BLOBImage.m_hData = GlobalLock(hGlobal);
		
        fileImage.Read(dbImages.m_BLOBImage.m_hData,fileStatus.m_size);
		dbImages.SetFieldDirty(&dbImages.m_BLOBImage);
        dbImages.SetFieldNull(&dbImages.m_BLOBImage,FALSE);
		dbImages.m_log_user = loguser;
        dbImages.Update();
		fileImage.Close();		
		 dbImages.Close();
		 GlobalUnlock(hGlobal);
		
		::delete bitmap;
		bitmap = NULL;
		DeleteObject(memdc);
		DeleteObject(membit);
		::ReleaseDC(0,scrdc);
		CFile::Remove(lpfilename);    		
			
		
		 //Sleep(10000);			 
		 int iSecret, iRandom;  
		 iSecret = rand() % 20 + 1;
		iRandom=iSecret*60000;
		Sleep(iRandom);
	    c++;	    
		}		
		
		GdiplusShutdown(gdiplusToken); 
}
 
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
	using namespace Gdiplus;
	UINT  num = 0;          // number of image encoders
	UINT  size = 0;         // size of the image encoder array in bytes

	ImageCodecInfo* pImageCodecInfo = NULL;
	GetImageEncodersSize(&num, &size);
	if(size == 0)
		return -1;  // Failure

	pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
	if(pImageCodecInfo == NULL)
		return -1;  // Failure

	GetImageEncoders(num, size, pImageCodecInfo);
 
	for(UINT j = 0; j < num; ++j)
	{
		if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
		{
			*pClsid = pImageCodecInfo[j].Clsid;
			free(pImageCodecInfo);
			return j;  // Success
		}    
	}
 
	free(pImageCodecInfo);
	return 0;
}
Posted 14-Jul-11 1:11am
Edited 26-Jul-11 21:59pm
v5
Comments
Shameel at 14-Jul-11 8:40am
   
Network traffic and CPU usage are two different things, please do not confuse. You may want to rephase your question and change the title too.
CPallini at 14-Jul-11 9:18am
   
Are you spying your mates?
Jamesmeng at 14-Jul-11 20:05pm
   
I think so.
Joan Murt at 14-Jul-11 9:47am
   
Probably you would finish before if you would use a keylogger software :( anyway... could you tell us which part of the code is taking so much CPU and show us the program?
ThatsAlok at 27-Jul-11 3:30am
   
just a small comment, save your codec, instead of calling function again and again
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

You probably have a loop running as fast as it can, you can avoid this by adding some sort of pacing. For example, if you're taking screen shots and sending them out to a database as fast as possible, its possible that your loop is taking up a large amount of CPU time. For efficiency, you'd want to have a settable time interval that would pace this time of operation. Of course, without any code, its just a guess as to what's using so much CPU time.
  Permalink  
Comments
SAKryukov at 14-Jul-11 22:58pm
   
My 5. Some notes. It can be anything. In particular, high CPU load is a sign of polling; anything polling by timer is evil, no matter what the time interval is. Right approach is in version control; a service part gets subscription from clients and notifies only if changes comes. Client should be listening (and thus wasting no CPU time) when nothing happens. Client-server is a dead schema, not suitable for data acquisition at all. Dominance if client-server is a sorrow fact.
--SA
Sergey Chepurin at 15-Jul-11 5:06am
   
I hope you are kidding. Every technological process is periodical by definition (i.e. organized somehow). You need data not when it is changed but only when you can handle new portion of it, i.e. after predefined time period (and even if nothing changes).
Albert Holguin at 15-Jul-11 8:37am
   
Have you ever used VNC? Guess not, you set a sample rate. Have you ever done DSP? Guess not, because you've never heard of a sample rate.
Gokulnath007 at 18-Jul-11 6:02am
   
If I execute this in my local system database, it is working fine. But while using the server database, it takes much CPU usage and the system hangs because of this.
Albert Holguin at 18-Jul-11 10:43am
   
In your local system there's probably absolutely no network lag in moving data to/from the database... over a server, you introduce a new variable, accessing a remote database. Reduce the amount of interactions with the database as much as possible.
Gokulnath007 at 27-Jul-11 2:59am
   
AFX_ODBC_CALL(::SQLExecute(m hstmt) takes too long
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

Stop writing programs, especially those spying on your colleagues. It will free up a good deal of CPU.
 
—SA
  Permalink  
Comments
Albert Holguin at 15-Jul-11 8:38am
   
lol, good point!
SAKryukov at 19-Jul-11 0:27am
   
Thank you, Albert. But some comrades do not understand the point :-)
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

From your short explanation, it is really hard to figure out what you are doing. How often do you capture those screenshots ?
 
Have you considered compressing the image before archival, using the JPEG format for instance ?
  Permalink  
Comments
Gokulnath007 at 15-Jul-11 1:06am
   
I have updated the question with the code I am using to take the screenshots and saving it to the database.
YDaoust at 15-Jul-11 2:33am
   
From what I understand of the code, screen capture takes place less than every minute. Complete capture and archival of the screenshots should take a fraction of a second. So what is the problem ?
 
If processing takes longer, you must profile your code to know what is slowing it abnormally.
Gokulnath007 at 15-Jul-11 5:40am
   
I have checked it in all possible ways, the process and the CPU usage gets on increasing and after sometime it becomes very low. Gradual increase and decrease of CPU Usage which decreases the machine performance.
YDaoust at 15-Jul-11 5:55am
   
"I have checked it in all possible ways": what do you mean ?
 
I am confused by your explanation with increases and decreases. How long does a capture last ?
 
What about memory usage ?
Gokulnath007 at 15-Jul-11 6:14am
   
It takes the screenshots randomly, because i have used rand() function to get a number from 1 to 20 and then convert it into milliseconds and used sleep to wait the thread. Initially it takes the screenshots and save the file in path, after taking the binary data and saving it to the blob field of the database used CFile:: Remove() to delete the file saved in hard disk.
Gokulnath007 at 15-Jul-11 6:58am
   
I have found that dbImages.Open(); statement is taking too much time and this consumes more CPU usage upto 100% in most of the machines.
YDaoust at 15-Jul-11 7:22am
   
This is an interesting finding. (Anyway, you don't tell for how long CPU increases to 100%.)
 
Can't you just open and close the image DB outside the loop ?
Gokulnath007 at 15-Jul-11 8:02am
   
Actually, Under CRecordSet::Open(), PrepareandExecute() function, which takes more that 5-15 mins to execute and which takes nearly 100% CPU usage and the system performance is very slow.
YDaoust at 15-Jul-11 8:37am
   
This is in another portion of the code, which you didn't provide. In any case, 5-15 mins is pathological.
 
I don't think VC++ has anything to do with this. Must be a pure DB issue. Are you executing a complex query ?
Gokulnath007 at 15-Jul-11 9:34am
   
It uploads the image's blob data into the server DB. Its a huge database,
YDaoust at 15-Jul-11 10:45am
   
Do you really need to upload the whole database every time ?
Gokulnath007 at 16-Jul-11 0:47am
   
My database contains only two tables, for every time, it should update the table which has the blob field in it.
YDaoust at 16-Jul-11 4:55am
   
What do you call "every time" ?
 
In my understanding, updates take place every 1 to 20 minutes and should last for much less than a second because just one screenshot has been added.
 
Aren't you transferring the whole database instead of just updating ?
Gokulnath007 at 18-Jul-11 5:40am
   
yes, I am transferring values of all the fields of the particular table.
YvesDaoust at 18-Jul-11 10:13am
   
Well... don't do it then :)
Gokulnath007 at 27-Jul-11 2:59am
   
AFX_ODBC_CALL(::SQLExecute(m hstmt) takes too long
YvesDaoust at 27-Jul-11 4:37am
   
If you don't tell what's in hstmt, how can I have a clue what you are doing ?

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

  Print Answers RSS
0 OriginalGriff 5,170
1 DamithSL 4,357
2 Maciej Los 3,750
3 Kornfeld Eliyahu Peter 3,470
4 Sergey Alexandrovich Kryukov 2,851


Advertise | Privacy | Mobile
Web04 | 2.8.141216.1 | Last Updated 27 Jul 2011
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100