Terminating a running while loop at run-time - runtime

I have some problems with controlling a while loop inside an event structure.
Say I have an iterative procedure and I want to stop the iterations during run-time (say to check out the results).
while(resid > 1e-10 )
{
for (int iter = 0;iter < 1000;iter++)
{
// some thing //
}
}
I have 3 buttons ("Start Running, Stop Running, Quit Program"). When the while loop is running, it should be possible to stop the running by clicking on "Stop Running", but this does not work.
I am not saying it has to be buttons but it could be a console app and the termination is done by writing something on the console.
Has anyone an idea on it can be implemented?
Thanks a lot and best regards,
Mohammed

You need to check for "Button was pressed" inside the loop and then break out of the loop if it was detected.

Related

Why am I not allowed to break a Promise?

The following simple Promise is vowed and I am not allowed to break it.
my $my_promise = start {
loop {} # or sleep x;
'promise response'
}
say 'status : ', $my_promise.status; # status : Planned
$my_promise.break('promise broke'); # Access denied to keep/break this Promise; already vowed
# in block <unit> at xxx line xxx
Why is that?
Because the Promise is vowed, you cannot change it: only something that actually has the vow, can break the Promise. That is the intent of the vow functionality.
What are you trying to achieve by breaking the promise as you showed? Is it to stop the work being done inside of the start block? Breaking the Promise would not do that. And the vow mechanism was explicitly added to prevent you from thinking it can somehow stop the work inside a start block.
If you want work inside a start block to be interruptible, you will need to add some kind of semaphore that is regularly checked, for instance:
my int $running = 1;
my $my_promise = start {
while $running {
# do stuff
}
$running
}
# do other stuff
$running = 0;
await $my_promise;
Hope this made sense.
The reason why you cannot directly keep/break Promise from outside or stop it on Thread Pool are explained here in Jonathans comment.
Common misuse of Promises comes from timeout pattern.
await Promise.anyof(
start { sleep 4; say "finished"; },
Promise.in( 1 )
);
say "moving on...";
sleep;
This will print "finished". And when user realize that the next logical step for him is to try to kill obsolete Promise. While the only correct way to solve it is to make Promise aware that its work is no longer needed. For example through periodically checking some shared variable.
Things gets complicated if you have blocking code on Promise (for example database query) that runs for too long and you want to terminate it from main thread. That is not doable on Promises. All you can do is to ensure Promise will run in finite time (for example on MySQL by setting MAX_EXECUTION_TIME before running query). And then you have choice:
You can grind your teeth and patiently wait for Promise to finish. For example if you really must disconnect database in main thread.
Or you can move on immediately and allow "abandoned" Promise to finish on its own, without ever receiving its result. In this case you should control how many of those Promises can stack up in background by using Semaphore or running them on dedicated ThreadPoolScheduler.

How to delete the dispatched block using GCD

I have this code:
_myQueue = dispatch_queue_create("com.myapp", DISPATCH_QUEUE_SERIAL);
_mainQueue = dispatch_get_main_queue();
and lot of this block that require some seconds (or minutes)
dispatch_async(_myQueue,
^{
if(canRun){
dispatch_async(_mainQueue,^{/* updating interface here */});
// code here
}
});
My app have a "Stop" button to try stopping all job, and the BOOL "canRun" help me to execute all blocks w/o do nothing.....but always I have to wait the completition of each block until the queue come 0.
Is there any way to instantly "clean" the queue istead doing that?
The aim is to stop processes and to start over without closing and reopening the application.
This project works under ARC.
You can cancel them if you take a few extra steps to creat a dispatch_source object and keep a reference to it.
Review this for starters
https://developer.apple.com/library/mac/documentation/Performance/Reference/GCD_libdispatch_Ref/index.html
There are functions to pause, resume and cancel.

How to use NSAutoreleasePool in AppleScriptObjC

I am wondering how to stop another function from a background function.
In addition, I have to drain NSAutoreleasePool, but I don't know how to do it.
I think this app sometimes freeze if I don't release pool.
property i : 0
property myLabel : missing value
on myStartButtonHandler_(sender)
my performSelectorInBackground_withObject_("start", missing value) -- This code prevents "Stop" Button from freezing.
end myStartButtonHandler_
on myStopButtonHandler_(sender)
-- I want to stop start() function and drain AutoreleasePool!
-- I don't want to use "quit me" because I want to stop only start() function.
end myStopButtonHandler_
on start()
repeat
set i to i + 1
myLabel's setIntegerValue_(i)
delay 1
end repeat
end start
You can download source code from here --> https://dl.dropboxusercontent.com/u/97497395/test2.zip
For your information, I am using Xcode 4.6.3.
EDIT
My script has delay 300 command, so I can't stop the function with checking the value of the variable. Sorry.
EDIT
I conceived of an idea to stop the function while delay commands.
on start()
repeat 5 times
if i = 1 then
error -128
else
delay 60
end repeat
end start
on myStopButtonHandler_(sender)
set i to 1
end myStopButtonHandler_
I can stop the function in 60 seconds, but I can't stop it as soon as I push the stop button. So, I am still waiting for your answer.
An easy way to stop the function is to have a variable. Check the value of the variable. If the variable is true for example then you can exit your repeat loop and drain the autorelease pool. I'm running to work now so no time to write code. Good luck.
EDIT: If you use an NSTimer to fire your handler, as opposed to a repeat loop, then you can invalidate the timer to stop it from running the handler. I use this to invalidate a timer because you should always check that the timer is valid before invalidating it... it will crash if you invalidate a non-valid timer.
-(void)deleteMyTimer {
if ([myTimer isValid]) {
[myTimer invalidate]
myTimer = nil;
}
}

MsWord.BackgroundPrintingStatus

I have an instance of a word document running (opened through a New Word.Application). I have populated the document and sent it to print, however, if i then use the Msword.application.quit method as the next statement it cancels the print job
I have put in a do while MsWord.BackgroundPrintingStatus = 1 loop in but this then goes into an infinite loop.
stepping into the code and giving the print job time to run before continuing to the quit command works fine and the MsWord.BackgroundPrintingStatus does return to 0.
Why would a do while loop go into an infinite loop while waiting for the status to change?
OK found a way to do it. put the quit in a do while printingstatus = 0

Go Threads - Pause Execution

I have two threads of execution like,
Routine 1 {
// do something
}
Routine 2 {
// do something
}
Is it possible to pause execution of routine 2 from routine 1 for few seconds and how can it possible ?
It is not possible to control the execution of one goroutine from another. Goroutines are cooperative. They don't dominate each other.
What you could do is put points in routine 2 where it checks whether it's allowed to proceed. Such as
// do stuff
select {
case <-wait:
<-resume
default:
}
Then routine 1 could tell routine 1 could send a signal to routine 2 telling it to wait:
wait <- true
// whatever stuff goes here
resume <- true
Why do you want to pause the goroutine? That might help answer your question better. It is best to start from a place of what you are trying to do rather than how you want to do it. That way, you can find out how to achieve what you actually want in the language, rather than being given poor substitutes for the method of achieving it that you'd originally imagined.
From one thread, it is not possible to control another thread implicitly. You can do like this, define a bool and based on that you can pause by time.Sleep(2*1e9).

Resources