 |
|
 |
Hello Mauro Leggieri,
Thanks for your effort. I am a newbie and this is definitely something I could use as I would like to do some background processing in my Windows Application (CWinApp)! However, can we start/stop these background tasks without a Dialog? If so, could you guide me accordingly. Thanks in advance and appreciate your response/support.
Best Wishes,
IScribe
-- modified at 21:44 Sunday 3rd June, 2007
|
|
|
|
 |
|
 |
Hi!
In functions OnBtnStartStop() and RunBackgroundTask() from the demo dialog class, try and avoid the CWnd* wnd pointer. It's useless and it's more prone to errors. The functions simply could look like this:
void CBackgroundTaskDialogDemoDlg::OnBtnStartStop()
{
if (IsBackgroundTaskRunning() == FALSE)
{
if (StartBackgroundTask() < 0)
{
GetDlgItem(IDC_STC_PROGRESS)->SetWindowText(
_T("Error: Cannot start background thread."));
return;
}
GetDlgItem(IDC_BTN_STARTSTOP)->SetWindowText("Stop");
}
else
{
StopBackgroundTask();
GetDlgItem(IDC_STC_PROGRESS)->SetWindowText(_T("Thread was
stopped."));
GetDlgItem(IDC_BTN_STARTSTOP)->SetWindowText("Start");
}
return;
}
and
void CBackgroundTaskDialogDemoDlg::RunBackgroundTask()
{
TCHAR buf[1024];
int i;
for (i = 0; i < 500; i++)
{
if (CheckForBackgroundTaskAbort() != FALSE)
return;
_stprintf(buf, _T("Counting %ld of 500"), i+1);
GetDlgItem(IDC_STC_PROGRESS)->SetWindowText(buf);
Sleep(10);
}
GetDlgItem(IDC_STC_PROGRESS)->SetWindowText(_T("Thread has finished
successfully."));
GetDlgItem(IDC_BTN_STARTSTOP)->SetWindowText("Start");
return;
}
The code is also more readable.
Greatings,
Christian.
I am in love with VC++
|
|
|
|
 |
|
 |
Hi,
I usually use the CWnd pointer when I have to call many functions in the object.
If I have to do:
GetDlgItem(IDC_STC_PROGRESS)->SetWindowText(...
GetDlgItem(IDC_STC_PROGRESS)->SendMessage(...
GetDlgItem(IDC_STC_PROGRESS)->MoveWindow(...
I prefer to do
CWnd *lpWnd;
lpWnd = GetDlgItem(IDC_STC_PROGRESS);
lpWnd->SetWindowText(...
lpWnd->SendMessage(...
lpWnd->MoveWindow(...
It is faster because it works like a cache avoiding asking the s.o. for the handle of the child control each time I want to access it.
Also remember that it is a demo code. Always improvements can be done.
Best regards,
Mauro.
|
|
|
|
 |
|
 |
Ok!
I get the point.
Thanks.
Best wishes,
Christian.
I am in love with VC++
|
|
|
|
 |
|
 |
Good luck! Mauro.
|
|
|
|
 |
|
 |
Thank you for your improved codes.
- OnBtnStartStop();
- RunBackgroundTask();
void CBackgroundTaskDialogDemoDlg::OnBtnStartStop()
{
if (IsBackgroundTaskRunning() == FALSE)
{
if (StartBackgroundTask() < 0)
{
SetDlgItemText(IDC_STC_PROGRESS, _T("Error: Cannot start background thread."));
return;
}
SetDlgItemText(IDC_BTN_STARTSTOP, _T("Stop"));
}
else
{
StopBackgroundTask();
SetDlgItemText(IDC_STC_PROGRESS, _T("Thread was stopped."));
SetDlgItemText(IDC_BTN_STARTSTOP, _T("Start"));
}
return;
}
void CBackgroundTaskDialogDemoDlg::RunBackgroundTask()
{
TCHAR buf[1024]={0,};
int i=0;
for (i=0; i < 500; i++)
{
if (CheckForBackgroundTaskAbort() != FALSE)
return;
_stprintf(buf, _T("Counting %ld of 500"), i+1);
SetDlgItemText(IDC_STC_PROGRESS, buf);
}
SetDlgItemText(IDC_STC_PROGRESS, _T("Thread has finished successfully."));
SetDlgItemText(IDC_BTN_STARTSTOP, _T("Start"));
return;
}
Taeha Kim
|
|
|
|
 |
|
 |
Thanks Kim.
The Sleep API is called in order to give a chance to the main thread to update the static control text. Sleep(1) should be enough.
Best regards,
Mauro H. Leggieri
|
|
|
|
 |
|
 |
Thank you for saying that and your article.
The article is very useful, I think.
By the way if the function (+pWnd) is inserted, cause access violation (0xC0000005).
The case is effected in simple robustness test, not in reliability one.
But this is irrelevant to your article and it's main objective.
It's only private tendency.
Cheers.
Taeha Kim
modified on Sunday, March 15, 2009 9:31 PM
|
|
|
|
 |
|
 |
I don't understand what do you mean with "funcion (+pWnd) is inserted". If I could help tell me
|
|
|
|
 |
|
 |
hi,
I have used your class in a lot of programs without a problem. However, now there is an issue because in this program the base class is not CDialog. You see, i am using Massimo Collurcio's UI class http://www.codeproject.com/miscctrl/hmxcontrols.asp[here^] and so my default constructors etc are different and causing errors. Is there a workaround for this?
thanks
"Some guys hack just to get themselves a girlfriend.What a pathetic reason huh ?"
|
|
|
|
 |
|
 |
Hi Kane,
I'm writing a fast answer because I'm at work. Please, let me know if you need further assistance.
You should add to BackgroundTaskDialog.cpp and .h the three dialog constructors...
CBackgroundTaskDialog(UINT uResourceID, CWnd* pParent = NULL);
CBackgroundTaskDialog(LPCTSTR pszResourceID, CWnd* pParent = NULL);
CBackgroundTaskDialog();
... and their implementations. The first one is already defined and implemented so you must add the second and the third.
In the implementation remember to call the corresponding CDialog base member function and put
hKillBackgroundThreadEvent = hDoneBackgroundThreadEvent = NULL;
lpBackgroundThread = NULL;
inside each constructor in order to initialize the variables.
Then you can change the HMXDialog.h file to make CHMXDialog a derived class of CBackgroundTaskDialog and the HMXDialog.cpp to call CBackgroundTaskDialog constructors instead of CDialog ones.
Best regards,
Mauro H. Leggieri
|
|
|
|
 |
|
 |
thanks with your help i managed to do it
"Some guys hack just to get themselves a girlfriend.What a pathetic reason huh ?"
|
|
|
|
 |
|
 |
Perfect.
Happy new year!
Mauro.
|
|
|
|
 |
|
 |
Hello,
alfter calling the StartBackgroundTask in the Initdialog functions
it returns -4!
Some known Problems?
regards
alex
|
|
|
|
 |
|
 |
Hi Alex,
As you see in the code, return value -4 implies that AfxBeginThread failed. I think ( really i'm guessing ) that the problem can be a memory, resource and/or gdi object leak in the code that is consuming system resources and then Windows cannot create the new thread.
Also, if you are using the StopBackgroundTask with a timeout, check if the function is really waiting the thread to finish or the function is terminating it.
Tell me if you have any news.
Best regards,
Mauro H. Leggieri
|
|
|
|
 |
|
 |
the program crashed!
Any new version?
|
|
|
|
 |
|
 |
Hi,
Sorry for the very late answer. I haven't made modifications to the code. Tell me more about the program crash so I can help you.
Best regards,
Mauro H. Leggieri.
|
|
|
|
 |
|
 |
I'm not the original poster of that question, but the crash that happens after starting/stopping a few times is still there it seems, so if you've fixed it, could you please post the code that needs to be changed?
Thanks.
// MCP, MCSD
// Software for animal shelters
// http://www.smartpethealth.com
|
|
|
|
 |
|
 |
Hi Dennis,
The version at codeproject is the latest and I make the test of starting and stopping the background task and seeing if there is any leak and nothing happens.
Please send me more details about the crash message and if it occurs in the demo app I uploaded. I want to resolve the problem if there is one.
Best regards,
Mauro H. Leggieri
|
|
|
|
 |
|
 |
Hi,
It's not a leak actually, it's a crash. I don't have the call stack at the moment (different computer), but if you do start-stop a few times quickly (15-20 times?), then it's going to come down crashing.
If you can't reproduce it, I'll try to get you a call stack and the offending variable sometime soon.
|
|
|
|
 |
|
 |
That was me, not logged in
// MCP, MCSD
// Software for animal shelters
// http://www.smartpethealth.com
|
|
|
|
 |
|
 |
Hi Dennis,
I made a very quick start/stop sequence as you (also using the spacebar to hit the button faster than mouse clicks) and nothing happens. I have a Pentium 4 1.8Ghz with 256mb ram. Send me the stack trace when you can to check.
Greetings, Mauro.
|
|
|
|
 |
|
 |
Hello, I am trying to set up a windows .net application form that apart from everything else would run a background process for downloading a web page and set it up as a backgound wallpaper. I am trying to use the code in the backgound task dialog, i've managed to define Runbackgroundtask with the code i would like to use but when i try to use the startbackgoundtask in the initialiseComponent in order to run the backgound process, i get a compile error of C2352: 'CBackgroundTaskDialog::StartBackgroundTask' : illegal call of non-static member function Any sugestions ? Thanks
|
|
|
|
 |
|
 |
Hi,
According to MSDN the problem arises when you call a nonstatic member from a static one or when you directly use the 'CBackgroundTaskDialog::StartBackgroundTask()' sentence to try to start the background task.
The CBackgroundTaskDialog is used as a base class of the dialog and you must call the StartBackgroundTask function using, for e.g., this->StartBackgroundTask();
If you can send me the piece of code that generates the problem I shall have a better view of the problem.
Best regards, Mauro H. Leggieri.
|
|
|
|
 |
|
 |
Hi,
I am trying to use your class for my program, but with a single-threaded program design it is not straightforward.
The effect I wanted is: during a lengthy operation (such as reading a large data file referenced in a document being loaded) a "Patience" dialog box with a simple message appears until the operation is complete. However, the lengthy operation is called in a sequence of other operations, so the main thread would have to "stop and wait" until the background thread finishes as if everything was in one thread. Still, if I simply displayed a dialog box and then go on processing, the program window would not be redrawn until the lengthy operation is completed.
To avoid a major redesign of existing code I made it work like this:
1. My code calls the DoModal() method of a dialog box displaying a "Please wait..." prompt (say: CPatience). DoModal() gives the "illusion" of a single-threaded operation.
2. In OnInitDialog() of CPatience I start a background thread to do lengthy processing (i.e. call StartBackgroundTask()).
3. After the lengthy operation is finished I call EndDialog(IDOK) of CPatience (from RunBackgroundTaskProc()).
It seems to work. Do you think it is ok or is there a major design-flaw in my logic?
Best regards,
Maciej.
|
|
|
|
 |