11-26-2013 02:05 AM - last edited on 12-19-2014 11:16 AM by dcarva
Hi all,
I have a code with two buttons placed on the panel, one is RUN, another is STOP. Initially, STOP is disabled and when I kick RUN, the STOP will be disable. But when STOP is kicked, the RUN will be activated.
#include "testimg.h"
#include <windows.h>
#include <utility.h>
#include "asynctmr.h"
#include <ansi_c.h>
#include <cvirte.h>
#include <userint.h>
#include <NIDAQmx.h>
#include "toolbox.h"
static int panelHandle = 0;
static int stoprun = 0;
int main (int argc, char *argv[])
{
int error = 0;
nullChk (InitCVIRTE (0, argv, 0));
errChk (panelHandle = LoadPanel (0, "testimg.uir", PANEL));
SetCtrlAttribute(PANEL, PANEL_STOPBUTTON, ATTR_DIMMED, TRUE);
errChk (DisplayPanel (panelHandle));
errChk (RunUserInterface ());
Error:
if (panelHandle > 0) DiscardPanel (panelHandle);
return 0;
}
int CVICALLBACK MainPanelResponse(int panel, int event, void *callbackData, int eventData1, int eventData2)
{
if (event == EVENT_CLOSE) QuitUserInterface (0);
return 0;
}
int CVICALLBACK RunButtonResponse (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
if (event==EVENT_COMMIT)
{
int N=20;
stoprun = 0;
SetCtrlAttribute(panel, PANEL_STOPBUTTON, ATTR_DIMMED, FALSE);
SetCtrlAttribute(panel, PANEL_RUNBUTTON, ATTR_DIMMED, TRUE);
for (int i=0; i<N; i++)
{
// some heavy task
// here I use Sleep instead
Sleep(5000);
ProcessSystemEvents();
Sleep(2000);
if (stoprun>0) break;
}
SetCtrlAttribute(panel, PANEL_STOPBUTTON, ATTR_DIMMED, TRUE);
SetCtrlAttribute(panel, PANEL_RUNBUTTON, ATTR_DIMMED, FALSE);
}
return 0;
}
int CVICALLBACK StopButtonResponse (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
if (event==EVENT_COMMIT)
{
stoprun = 1;
}
return 0;
}
My code is designed so to repeat a operation for N times after the START button is kicked. And if STOP button is kicked before the task is finished running. Stop the current application and return false; I wrote the code but it seems doesn't work. It seems that the application cannot be interrupted before the completete of the task. I don't know what's wrong with my code. If you have any experienence with that, could you please tell me what's wrong with my cdoe? Thanks.
Solved! Go to Solution.
11-26-2013 02:42 AM - edited 11-26-2013 02:43 AM
What you are seeing is the expected behaviour: in your loop inside the run button, you have a 5 seconds wait in which the system is frozen, next another 2 sec with the system frozen again. For simulation puroposes you should modify the code this way:
double tini; tini = Timer ();
requestToStop = 0; while (Timer () - tini < 5.0 || requestToStop) { ProcessSystemEvents (); sleep (50); }
The Stop button then must raise a global variable that stops the loop (requestToStop in my example above).
In actual code, such a long lasting process should not be handled inside a control callback: you should place it elsewhere depending on how you want to structure your code so to leave the UI responsive. Available alternatives are:
- A UI timer callback
- An Asynchronous timer callback (similar to the preceding one but executed in a separate thread)
- A separate thread issued with CmtScheduleThreadPoolFunction
Whichever is the solution, the stop button must be handled inside the code by raising a signal that let the processing stop in a secure manner.