I want my simulation to stop as soon as a specific condition in the code is met. By 'stop' I mean it should pause the simulation as if I pressed stop button in the simulation window. So that I could continue the simulation with a slower speed from this moment.
Is there a way to do it from the module code?
There is no API for managing the GUI's run state. The reason is, that you can run the simulation also in Cmdenv without recompiling the code and it's not possible/makes no sense to pause a simulation in Cmdenv.
You can however do a trick, because the simulation is repeatable:
Add some code that prints out the event number when the specific condition occurred.
Run the simulation and note the event number it prints out when the simulation is run.
Now start the simulation again (with the same parameters) but use the "Run until... / Event number" and specify the event number where the GUI should stop.
The alert() method is very convenient to implement #Rudi trick.
In GUI (Run, Fast, and Express) alert() pauses the simulation, shows a message box with own text, waits for user reaction, and then continues the simulation in the same mode. In Cmdenv it shows a text in console without pausing a simulation.
Here is a sample code that prints current event number using this method:
char text[128];
sprintf(text,"Event number: %lld", getSimulation()->getEventNumber());
getSimulation()->getActiveEnvir()->alert(text);
After learning this event number one should do what #Rudi has proposed in the last bullet.
Related
My problem is this. I have check box which when checked starts while loop. At that while loop there is createprocess function. While checkbox is marked as checked, function repeats it self again and again. Problem is that while loop is running I can't push check box again to change it's values and stop the process. I think that here is needed something like two parallel process working at the same time, but I am not sure. My question would be:
* Is there a way to access my controls while while loop is running?
* Or maybe I should use something else instead of while process?
Suggestions or some kind of example would be appreciated.
The problem is that you are running the loop in the same thread that owns the CheckBox, and that loop is blocking the thread from processing new messages. That is why you are not able to uncheck the CheckBox (or do anything else with your UI).
You need to either:
move the loop to a worker thread. When the CheckBox becomes checked, start the thread. When the CheckBox becomes unchecked, stop the thread. Do not block the dialog's thread at all. This is the best option.
break apart your loop and make it event-driven. When the CheckBox becomes checked, post a custom window message to yourself. When you receive that message, if the CheckBox is still checked then perform one iteration of your loop and then post the message back to yourself again. Repeat until the CheckBox becomes unchecked. This option does not require any threads, but your UI will still be blocked during each individual iteration (but you will be able to uncheck the CheckBox in between iterations), unless...
Keep your existing loop code, but add an inner loop that calls MsgWaitForMultipleObjects() after CreateProcess() succeeds until the spawned process has exited. While waiting, whenever MsgWaitForMultipleObjects() tells you that a new message is waiting, you can pump the message queue and dispatch any messages that are retrieved. This is the least desirable option, but it requires the least amount of changes to existing code.
I am writing a kernel module that performs timing functions using an external clock. Basically, the module counts pulses from the clock, rolling over the count every so often. User processes can use an ioctl to ask to be woken up at a specific count; they then perform some task and invoke the same ioctl to wait until the next time the same count comes up. In this way they can execute periodically using this external timing.
I have created an array of wait_queue_head_ts, one for each available schedule slot (i.e. each "count", as described above). When a user process invokes the ioctl, I simply call sleep_on() with the ioctl argument specifying the schedule slot and thus the wait queue. When the kernel module receives a clock pulse and increments the count, it wakes up the wait queue corresponding to that count.
I know that it is considered bad practice to use sleep_on(), because there is potential for state to change between a test to see if a process should sleep, and the corresponding call to sleep_on(). But in this case I do not perform such a test before sleeping because the waking event is periodic. It doesn't matter if I "just miss" a waking event because another will come shortly (in fact, if the ioctl is invoked very close to the specified schedule slot, then something went wrong and I would prefer to wait until the next slot anyway).
I have looked at using wait_event_interruptible(), which is considered safer, but I do not know what to put for the condition argument that wait_event_interruptible requires. wait_event_interruptible will check this condition before sleeping, but I want it to always sleep when the ioctl is invoked. I could use a flag that I clear before sleeping and set before waking up, but I'm worried this might not work in the case that there are multiple processes in the wait queue - one process might finish and clear the flag before the next is woken up.
Am I right to be worried about this? Or are all processes in a wait_queue guaranteed to be woken up before any of them run (and could therefore clear the flag)? Is there a better way to go about implementing a system such as this one? Is it actually okay to just use sleep_on()? (If so, is there a version of sleep_on() that is interruptible?)
Interruptible version of sleep_on is interruptible_sleep_on. Note, that sleep-functions have been removed since kernel 3.15.
As for wait_event_interruptible, requirement I want it to always sleep when the ioctl is invoked. is uncommon for it. You may use a flag, but this flag should be per-process (or per-schedule slot). Or you may modify count for wait to be at least current_count + 1.
In such uncommon scenario, instead of macro wait_event_interruptible you may use blocks it consist of, and arrange them in the way you need. Generally, any waiting can be achived in that way.
Currently, I call DoEvents in order to check if Button Foo in Form Bar has been clicked. This approach works but it takes too much processing power, delaying the program.
I believe that the delay could be reduced if I could only check if Button Foo has been clicked, instead of all the other forms that DoEvents has to go through.
Any ideas on how can I check if Button Foo was clicked?
VB6 was not really designed for what you seem to be doing (some sort of long-running straight-line code that does not exit back to give the message loop control). Normally such a task would be delegated to a worker thread, and in VB6 this means some external component implemented in C++ most of the time.
There are only a very few kinds of approaches to take to do this for your ad-hoc logic:
Hacks creating separate threads via API calls, not very reliable in VB6 for a number of reasons.
A tricky thread-per-object ActiveX EXE implementing a class to handle your long-running workload.
A separate non-interactive worker process to be run and monitored by your GUI program.
That's pretty much it.
The prescribed method of doing this sort of thing is described in the VB6 documentation. You break your long-running loop up and invert the logic into a repeatable "quantum" of work (like n iterations of your processing loop), and maintain the state of your workload in Form-global data. Then you use a Timer control with its interval set to 1 or 16 (hardly matters, they normally take at least 16ms to trigger) and run your workload quantum within its event handler.
So if you simply had a loop that currently iterates 100,000 times doing something you might break it up so that it runs 500 times for each Timer tick. The quantum size will probably need to be tuned based on what is done within the loop - 500 is just a value chosen for illustration. You'll want to adjust this until it leaves the UI responsive without starving your background workload too much (slowing completion down).
If your code is heavy enough to not call DoEvents or just finish running periodically, then your app won't even know the button has been pressed. The DoEvents call allows windows, and your application to catch up on all notifications.
The correct way to resolve this is a worker thread (see this article on how to do something like this in VB6) but failing that, a periodic DoEvents is required and in turn, some re-entrancy blocking on the call into the long running code.
I am writing an audio recording application for WP7. I have a DispatcherTimer object in my ViewModel class, that when the recording is happening, counts the elapsed seconds to show the length of the recording to a user. I have the following problem with the app:
The tick interval for the DispatcherTimer is set to one second (1000) ms.
When I press the start button, the DispatcherTimer starts.
When I press the stop button, the DispatcherTimers thread exits. (in a second!, thought I didn't intend it to be that way))
If I do press the start button after pressing stop to swiftly (less then a second inbetween), my DispatcherTimer fails to start again, since it hasn't yet stopped. (it's thread hasn't exited)
Basically, my biggest concern is why does DispatcherTimer has to wait until it's time for its tick, to realize that it has been stopped, and the thread it created to perform ticks in has to exit?
How can I work around this problem? Thank you.
DispatcherTimers are not guaranteed to execute exactly when the time interval occurs, but they are guaranteed to not execute before the time interval occurs. This is because DispatcherTimer operations are placed on the DispatcherTimer queue like other operations. When the DispatcherTimer operation executes is dependent on the other jobs in the queue and their priorities.
Reference: http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer(v=VS.95).aspx
You should better use a System.Threading.Timer, which is a timer class that fires on a separate thread. This is good for purely numerical timing, where you're not trying to update the UI, etc.
I want to write a simple program that does nothing but does not easily terminate when asked to. I want to see the Windows dialog box which says, "this program is not responsive, do you want to wait to let it finish what it's doing, or terminate it now?". After the user chooses "terminate it now", it should, of course, exit.
The reason I want this is for a testing environment. I want to test a scenario in which the user is trying to log out, but the system doesn't log them out right away, because of an unresponsive program.
I tried responding to WM_DESTROY by calling Sleep(), but that doesn't seem to do it. The program still terminates immediately when killed from the Task Manager. Again, I'm not trying to write something truly "unkillable", just a simple program which makes that dialog box come up asking if the user wants to wait for the program to finish.
Thanks very much for any help.
You can try modifying your main-message loop . Use PeekMessage(...) with NO_REMOVE and ignore WM_QUIT messages
EDIT: Remove every message (except WM_QUIT) before processing it (GetMessage( &msg ,msg.hWnd ,msg.message ,msg.message ))