how to run a series of codes repeatedly at a regular time interval until a condition is satisfied - vb.net

I want to run the series of codes continuously at a regular time interval and stop when a given condition is met

You need a combination of looping or repetition, along with a timestamp check.
There are several options available in VB.Net:
Use a Do Until or Do While loop with a delay
Example:
Do Until Now > [time]
[code]
System.Threading.Thread.Sleep([delay in milliseconds])
Loop
Advantage: Reliable and simple.
Disadvantage: Ties up your processing, unless use some kind of multithreading, like a BackgroundWorker.
Use a Timer
Example:
Inside the Timer.Tick Event:
If Now < [time]
[code]
Else
Timer.Enabled = False
End If
Advantage: Simple and does not tie up your main thread.
Disadvantage: Sometimes can skip ticks.

Related

How to use indivdual condition in AnyLogic agent based simulation

I am trying to simulate a customer by using agents. In the statechart I built, I would like to apply to each individual agent the waiting time spent in the system by defining different variables:
WatingTimeStart, WaitingTimeEnd and WaitingTime
In order to assign the waiting time to each agent I am using the following command in the transition prior to the state I would like to apply the condition:
this.WaitingTimeStart=time();
In the next State I am then using the following:
this.WaitingTimeEnd=time();
this.WaitingTime=this.WaitingTimeEnd-this.WaitingTimeStart;
Followed by the next transition with the condition (TolerarableWaitingTime is a pre-defined Variable)
this.WaitingTime>TolerarableWaitingTime;
My Problem is the transition does not accept the condition and is not processing the agents to the next state.
I probably make a mistake in:
assinging the variable WaitingTime to each agent
applying the condition correcly
Thanks a lot for any thoughts.
Bastian
It was difficult to understand your question, but here it goes: first, you don't need to use "this", you can just do in the transition previous to the state in question:
WaitingTimeStart=time();
also by convention your variables should start with a low case letter, so it should be waitingTimeStart.
But you don't really even need that code and you are overcomplicating yourself... if you want to apply a waiting time (or a delay) you don't need a conditional transition, you can just use a timeout transition instead, where the timeout time is equal to TolerarableWaitingTime

Confusion with writing a game loop

I'm working on a 2D video game framework, and I've never written a game loop before. Most frameworks I've ever looked in to seem to implement both a draw and update methods.
For my project I implemented a loop that calls these 2 methods. I noticed with other frameworks, these methods don't always get called alternating. Some frameworks will have update run way more than draw does. Also, most of these types of frameworks will run at 60FPS. I figure I'll need some sort of sleep in here.
My question is, what is the best method for implementing this type of loop? Do I call draw then update, or vice versa? In my case, I'm writing a wrapper around SDL2, so maybe that library requires something to be setup in a certain way?
Here's some "pseudo" code I'm thinking of for the implementation.
loop do
clear_screen
draw
update
sleep(16.milliseconds)
break if window_is_closed
end
Though my project is being written in Crystal-Lang, I'm more looking for a general concept that could be applied to any language.
It depends what you want to achieve. Some games prefer the game logic to run more frequently than the frame rate (I believe Source games do this), for some games you may want the game logic to run less frequently (the only example of this I can think of is the servers of some multiplayer games, quite famously Overwatch).
It's important to consider as well that this is a question of resolution, not speed. A game with logic rate 120 and frame rate 60 is not necessarily running at x2 speed, any time critical operations within the game logic should be done relative to the clock*, not the tic rate, or your game will literally go into slow motion if the frames take too long to render.
I would recommend writing a loop like this:
loop do
time_until_update = (update_interval + time_of_last_update) - current_time
time_until_draw = (draw_interval + time_of_last_draw) - current_time
work_done = false
# Update the game if it's been enough time
if time_until_update <= 0
update
time_of_last_update = current_time
work_done = true
end
# Draw the screen if it's been enough time
if time_until_draw <= 0
clear_screen
draw
time_of_last_draw = current_time
work_done = true
end
# Nothing to do, sleep for the smallest period
if work_done == false
smaller = time_until_update
if time_until_draw < smaller
smaller = time_until_draw
end
sleep_for(smaller)
end
# Leave, maybe
break if window_is_closed
end
You don't want to wait for 16ms every frame otherwise you might end up over-waiting if the frame takes a non-trivial amount of time to complete. The work_done variable is so that we know whether or not the intervals we calculated at the start of the loop are still valid, we may have done 5ms of work, which would throw our sleeping completely off so in that scenario we go back around and calculate fresh values.
* You may want to abstractify the clock, using the clock directly can have some weird effects, for example if you save the game and you save the last time you used a magical power as a clock time, it will instantly come off cooldown when you load the save, as that is now minutes, hours or even days in the past. Similar issues exist with the process being suspended by the operating system.

Killing a BPMN subprocess with an external throw event

I have a usage issue I need some advice on.
I have a process with a main flow which loops, retrying a task every n hours until either a condition is met or a timeout is reached. So far so good.
There is a transactional sub process triggered to run in parallel to this main loop which, for as long as this main loop is active, carries out its own looping behaviour (every x days). This second loop should run for as long as the main loop continues, and be killed as soon as the main loop reaches one of its progression criteria.
The way I'd like to model it would be to use a message/signal throw event from the main flow after it has passed its progress criteria, with a corresponding catch message/signal as a boundary event on the sub process, which then triggers a sub process end/terminate event inside the boundaries of the sub process.
I've looked long and hard at resources and the standard, and I can't see any examples of people using boundary events in this way (as an input from outside the sub process, leading to an end event inside the sub process). Any idea if this is valid?
If not valid, anyone have a better method for having a main flow kill a sub process in this way?
Main Process: Start, parallel gateway (fork), first branch contains subprocess 1, second branch contains subprocess 2, exclusive gateway (join), end.
Subprocess 1: Start, loop, exit from the loop under some condition, then end.
Subprocess 2: Start, loop, no end node.
This way, subprocess 2 can't cause an end of looping of its own. But subprocess 1 can end, and by the exclusive join gateway, subprocess 2 will end as well.
I'm not quite sure whether a parallel fork, followed by an exclusive join, is actually allowed formally in BPMN. But some tools can handle it, and I received this hint from a tool vendor (Bonita).

Unable to interrupt psychopy script, event.getKeys() always empty

I'm new to psychopy and python. I'm trying to program a way to quit a script (that I didn't write), by pressing a key for example. I've added this to the while loop:
while n < total
start=time.clock()
if len(event.getKeys()) > 0:
break
# Another while loop here that ends when time is past a certain duration after 'start'.
And it's not working, it doesn't register any key presses. So I'm guessing key presses are only registered during specific times. What are those times? What is required to register key presses? That loop is extremely fast, sending signals every few milliseconds, so I can't just add wait commands in the loop.
If I could just have a parallel thread checking for a key press that would be good too, but that sounds complicated to learn.
Thanks!
Edits: The code runs as expected otherwise (in particular no errors). "core" and "event" are included. There aren't any other "event" command of any kind that would affect the "key press log".
Changing the rest of the loop content to something that includes core.wait statements makes it work. So for anybody else having this difficulty, my original guess was correct: key presses are not registered during busy times (i.e. in my case a while statement that constantly checks the time), or possibly only during specific busy times... Perhaps someone with more knowledge can clarify.
....So I'm guessing key presses are only registered during specific
times. What are those times? What is required to register key
presses?....
To try and answer your specific question, the psychopy api functions/methods that cause keyboard events to be registered are ( now updated to be literally every psychopy 1.81 API function to do this):
event.waitKeys()[1]
event.clearEvents()[1]
event.getKeys()[2]
event.Mouse.getPressed()
win.flip()
core.wait()
visual.Window.dispatchAllWindowEvents()
1: These functions also remove all existing keyboard events from the event list. This means that any future call to a function like getKeys() will only return a keyboard event if it occurred after the last time one of these functions was called.
2: If keyList=None, does the same as *, else removes keys from the key event list that are within the keyList kwarg.
Note that one of the times keyboard events are 'dispatched' is in the event.getKeys() call itself. By default, this function also removes any existing key events.
So, without being seeing the full source of the inner loop that you mention, it seems highly likely that the event.getKeys() is never returning a key event because key events are being consumed by some other call within the inner loop. So the chance that an event is in the key list when the outer getKeys() is called is very very low.
Update in response to OP's comment on Jonas' test script ( I do not have enough rep to add comments to answers yet):
... Strange that you say this ..[jonas example code].. works
and from Sol's answer it would seem it shouldn't. – zorgkang
Perhaps my answer is giving the wrong understanding, as it is intended to provide information that shows exactly why Jonas' example should, and does, work. Jonas' example code works because the only time key events are being removed from the event buffer is when getKeys() is called, and any events that are removed are also returned by the function, causing the loop to break.
This is not really an answer. Here's an attempt to minimally reproduce the error. If the window closes on keypress, it's a success. It works for me, so I failed to reproduce it. Does it work for you?
from psychopy import event, visual, core
win = visual.Window()
clock = core.Clock()
while True:
clock.reset()
if event.getKeys():
break
while clock.getTime() < 1:
pass
I don't have the time module installed, so I used psychopy.core.Clock() instead but it shouldn't make a difference, unless your time-code ends up in an infinite loop, thus only running event.getKeys() once after a few microseconds.

Threadpool to Task Conversion

My current solution uses the ThreadPool to process transactions. Every couple minutes I grab 1-200 transactions and queue each one via the QueueUserWorkItem function. Something like this where 'trans' is my collection of transactions:
For Each t As ManagerTransaction In trans
Threading.ThreadPool.QueueUserWorkItem(AddressOf ProcessManagerTransaction, t)
Next
I want to switch it over to use the TPL, however, after much research I am still unsure of the best way to go about it. I have the following options yet I haven't been able to find a general consensus on what the best practice is.
1) Threading.Tasks.Parallel.ForEach(trans, AddressOf ProcessManagerTransaction)
Where "t" is an individual transaction in my "trans" collection
2) Task.Factory.StartNew(AddressOf ProcessManagerTransaction, t)
2a) Task.Factory.StartNew(Sub() ProcessManagerTransaction(t)
And this combination of the two:
3) Task.Factory.StartNew(Function() Parallel.ForEach(trans, AddressOf ProcessManagerTransaction))
The first option is generally perferrable because it does everything you want: parallelization and propagation of errors. Options 2 and 3 require additional means to propagate errors.
Option 2 might come into play if you require having tasks so you can compose them with other tasks.
I do not really see a case where I would use option 3.