How to force WinForms into ->Show() - winforms

The following code fragment uses a WinForms instance with a button to start a countdown and a textbox to follow it. To simulate a calculation process of any duration, a Fibonacci number is calculated within each count. Regardless of how much time the form element has to react, the countdown is not displayed. Only when everything is finished, the result alone is displayed.
Put simply, I wonder where the event handler gets the idea that it has to wait for the whole process to finish. The calculation has nothing to do with the form element. Actually, it would make more sense to get the calculation 'politely' wait for the UI element, if it lacks the time to display the desired intermediate steps and thus pauses for a moment. Is there any other methode than ->Show() to force a Form window refresh or is this waiting direction perhaps 'default' and can be optionally reversed?
main.cpp
---
form1.h / form1.cpp
---
// sub.cpp ...
void App1::Form1::button1_Click(System::Object^ sender, System::EventArgs^ e) {
unsigned res,dur=40;
System::String^ s;
Form^ fo = Form::ActiveForm;
for(int i = 10;i >= 0;i--) {
res = fibo(dur); // Loop: dur 5|80 ~ instantan|endless
s = i.ToString();
fo->Controls[1]->Text = s;
if(1) fo->Show(); } /// 0|1 no difference ??
s = res.ToString();
fo->Controls[1]->Text = s; }
unsigned fibo(unsigned n) { // time consuming calculation placeholder
long result = 0;
if (n == 0) return 0;
else if (n < 2) result = 1;
else result = fibo(n - 1) + fibo(n - 2);
return result; }
On my way to this question I found articles dealing with 'backgraoundWorker', hence the Fibonacci numbers. But what if the 100% is not known? This complicity all just to show that the process is still alive seems to me a bit break a fly on the wheel. Isn't that done more simple?

Related

How to add time delay to process more than 15 second in Actionscript?

So I have the following script to get all combination of an array :
'''
var value = new Array(40)
for (var i=0;i<value.length;i++){
value[i]=i;
}
var comb_list = getAllComb(value,24);
trace(comb_list)
function getAllComb(values:Array, r:int):Array{
var n = values.length;
var result = new Array();
var a = new Array(r);
// initialize first combination
for (var i = 0; i < r; i++) {
a[i] = i;
}
i = r - 1; // Index to keep track of maximum unsaturated element in array
// a[0] can only be n-r+1 exactly once - our termination condition!
var count = 0;
while (a[0] < n - r + 1) {
// If outer elements are saturated, keep decrementing i till you find unsaturated element
while (i > 0 && a[i] == n - r + i) {
i--;
}
result.push(a.slice())// pseudo-code to print array as space separated numbers
count++;
a[i]++;
// Reset each outer element to prev element + 1
while (i < r - 1) {
a[i + 1] = a[i] + 1;
i++;
}
}
return result;
}
'''
Running above script will get me:
Error: Error #1502: A script has executed for longer than the default timeout period of 15 seconds.
How to add time delay each 14 seconds passed so that I can run the script? So, after 14 seconds passed, the program will wait for 50ms then continue.
Any help appreciated.
So, there's a simple (well, pretty much so) and working example of how to separate the heavy calculations part from the main thread so the main thread (which also handles UI and external events like user input) would run smoothly, while being able to read the progress and the results of the heavy calculations going under the hood. It also is in a form of a single class, this could be a bit confusing (until you understand how it works) but still easy to handle and modify.
Although the background AVM goes along the same execution flow (code execution > graphics rendering > code execution > graphics rendering > and so on), there are no graphics to render hence there's no need to anyhow limit the code execution time. As a result Worker thread is not a subject to 15 seconds limit, which, somehow, solves the problem.
package
{
import flash.events.Event;
import flash.display.Sprite;
import flash.utils.ByteArray;
import flash.concurrent.Mutex;
import flash.system.Worker;
import flash.system.WorkerDomain;
public class MultiThreading extends Sprite
{
// These variables are needed by both the main and
// subservient threads and will actually point to
// the very same object instances, though from
// the different sides of this application.
private var B:ByteArray;
private var W:Worker;
private var M:Mutex;
// Constructor method.
public function MultiThreading()
{
super();
// This property is 'true' for the main thread
// and 'false' for any Worker instance created.
if (Worker.current.isPrimordial)
{
prepareProgress();
prepareThread();
startMain();
}
else
{
startWorker();
}
}
// *** THE MAIN THREAD *** //
private var P:Sprite;
private var F:Sprite;
// Prepares the progress bar graphics.
private function prepareProgress():void
{
F = new Sprite;
P = new Sprite;
P.graphics.beginFill(0x0000FF);
P.graphics.drawRect(0, 0, 100, 10);
P.graphics.endFill();
P.scaleX = 0;
F.graphics.lineStyle(0, 0x000000);
F.graphics.drawRect(0, 0, 100, 10);
F.x = 10;
F.y = 10;
P.x = 10;
P.y = 10;
addChild(P);
addChild(F);
}
// Prepares the subservient thread and shares
// the ByteArray (the way to pass messages)
// and the Mutex (the way to access the shared
// resources in a multi-thread environment
// without stepping on each others' toes).
private function prepareThread():void
{
M = new Mutex;
B = new ByteArray;
B.shareable = true;
B.writeObject(incomingMessage);
W = WorkerDomain.current.createWorker(loaderInfo.bytes);
W.setSharedProperty("message", B);
W.setSharedProperty("lock", M);
}
// Starts listening to what the background thread has to say
// and also starts the background thread itself.
private function startMain():void
{
addEventListener(Event.ENTER_FRAME, onFrame);
W.start();
}
private var incomingMessage:Object = {ready:0, total:100};
private function onFrame(e:Event):void
{
// This method runs only 20-25 times a second.
// We need to set a lock on the Mutex in order
// to read the shared data without any risks
// of colliding with the thread writing the
// same data at the same moment of time.
M.lock();
B.position = 0;
incomingMessage = B.readObject();
M.unlock();
// Display the current data.
P.scaleX = incomingMessage.ready / incomingMessage.total;
P.alpha = 1 - 0.5 * P.scaleX;
// Kill the thread if it signalled it is done calculating.
if (incomingMessage.terminate)
{
removeEventListener(Event.ENTER_FRAME, onFrame);
W.terminate();
B.clear();
B = null;
M = null;
W = null;
}
}
// *** THE BACKGROUND WORKER PART *** //
// I will use the same W, M and B variables to refer
// the same Worker, Mutex and ByteArray respectively,
// but you must keep in mind that this part of the code
// runs on a different virtual machine, so it is the
// different class instance thus its fields are not
// the same quite as well.
// Initialization.
private function startWorker():void
{
W = Worker.current;
M = W.getSharedProperty("lock");
B = W.getSharedProperty("message");
// Before starting the heavy calculations loop
// we need to release the main thread which is
// presently on W.start() instruction. I tried
// without it and it gives a huuuge lag before
// actually proceeding to intended work.
addEventListener(Event.ENTER_FRAME, onWorking);
}
private function onWorking(e:Event):void
{
removeEventListener(Event.ENTER_FRAME, onWorking);
var aMax:int = 10000000;
// Very very long loop which might run
// over the course of several seconds.
for (var i:int = 0; i < aMax; i++)
{
// This subservient thread does not actually need to
// write its status every single loop, so lets don't
// explicitly lock the shared resources for they
// might be in use by the main thread.
if (M.tryLock())
{
B.position = 0;
B.writeObject({ready:i, total:aMax});
M.unlock();
}
}
// Let's notify the main thread that
// the calculations are finally done.
M.lock();
B.position = 0;
B.writeObject({ready:i, total:aMax, terminate:true});
M.unlock();
// Release the used variables and prepare to be terminated.
M = null;
B = null;
W = null;
}
}
}
The error is not related to your script needing a time delay, the problem is your while loops are making your script unresponsive for more than 15 seconds, triggering the script timeout error. Action Script only allows 15 seconds for your script to execute.
Your first while loop looks problematic, and I'm unclear how the value of a[0] changes to end the loop. Add a break to the loop or make sure the condition changes to allow the loop to end, and you should solve your problem. You can also considering adding continue statements to your embedded while loops if they are only supposed to run one time after they find an unsaturated value.
Personally, since you are using ActionScript, I'd suggest using objects and listeners for value changes instead of iterating over arrays checking for changes.
You could also add a manual timeout for your while loop, but would need to include logic for it to pick up where it left off.
//Set timer to 14 seconds
timeout = getTimer() + 14000;
while(true && timeout > getTimer()){
trace("No Error");
}
If you were used Adobe Animate (Flash), you could change the "Script Time Limit" from Publish setting page.

How can i cooldown a loop in wpf ? Forest Fire Simulation

As a personnal work, i have to do a forest fire simulation in WPF.
I created all the map with a grid, and using an array.
The Fire is added through a random number ( in the array when ex : case = " Forest ").
The Fire is burning all the " forest case " and it depends on the wind ( N S E W, etc. ). Everything is working fine !
But i encounter a minor problem through the "fire loop". I mean, when i click on my button ' fire progress " ( which does the fire expansion ) all the forest case burns in a simultaneous way. ( the direction is correct, only the case with the right direction burns, the problem is not here ).
I wanted to cooldown this loop as each case after case will be burned, such as :
Case forest burns. Wait. Case forest 2 burns. And so on. And not all the cases in the right directions ( of the wind ).
I tried to use a dispatcher timer (TimeSpan ). But with no success. The only thing's working is the results of the loop is slowdown ( in seconds, milliseconds, days, whatever ). BUT all the cases changes in a same time. And not one by one.
Apologies if my english is not grammatically correct !
Here is my code :
private void DeclencherLeFeu()
{
TempsDuJeu = new DispatcherTimer();
TempsDuJeu.Interval = TimeSpan.FromSeconds(1);
TempsDuJeu.Tick += new EventHandler(OnTimerGameEvent);
TempsDuJeu.Start();
TempsQueMetLeFeuPourBrulerLaForet = new DispatcherTimer();
TempsQueMetLeFeuPourBrulerLaForet.Interval = TimeSpan.FromSeconds(8);
TempsQueMetLeFeuPourBrulerLaForet.Tick += new EventHandler(LesArbresSontCalcines);
TempsQueMetLeFeuPourBrulerLaForet.Start();
}
Note : LesArbresSontCalcines means in english that the trees are burned. It calls a function just as below :
private void LesArbresSontCalcines(object sender, EventArgs e)
{
for (int i = 0; i < 7; i++)
{
for (int j = 1; j < 10; j++)
{
if (MonTableau[i, j].Name == "Feu")
{
MonTableau[i, j].Source = new BitmapImage(new Uri(#"E:\tp999\wpfapplication13\wpfapplication13\ArbreMort1.gif", UriKind.RelativeOrAbsolute));
ImageBehavior.SetAnimatedSource(MonTableau[i, j], new BitmapImage(new Uri(#"E:\tp999\wpfapplication13\wpfapplication13\ArbreMort1.gif", UriKind.RelativeOrAbsolute)));
MonTableau[i, j].Name = "Noir";
}
}
}
}
Note : All the burning cases ( i use a fire.gif on the forest case ) are replacing with the ArbreMort1.gif (represents a blacked tree ).
In this part of my code, all the burning cases just change, in a same time, as a dead tree. And Not one by one.
I tried to do that the first burning case will be the first be darked ( with the ArbreMort1.gif) and so on till the ending burning case ( that will be the last to be transformed ).
How should i use this dispatcher timer ?
Thank you for your replies ! :)
You need to re-architect the handler. Create class members int[7] j and int i = 0;
Then inside handler index j array with i value to determine what j index is. Then increment j index then increment i mod 7. So now it will take 560 seconds to complete the sequence.
Thank you for your answers ! I will try to fix it ! :)
Have a nice day !

Multiple Timers Arduino

Hi I had a question about timers on that Arduino.
I have 5 physical buttons (piezos) that I am getting the analog input from. I am then having them write out a keyboard key. My issue is when one is hit I want it to be unable to hit for "x" amount of time. I tried using delay, but this ended up delaying the whole program, thus 2 buttons could not be hit at the same time. Could someone explain to me how to do this with timers? I want 5 separate timers 1 for each button that controls a Boolean, I would need 5 separate timers for 5 separate if statements. (See code).
//SNARE LOOP2
if(sensorValueA0 == 0)
{
if(SnareHit == false)
{
Keyboard.write(115);
SnareHit = true;
//Use timer here to delay this part of the system
SnareHit = false;
}
}
//BASS DRUM LOOP
if(sensorValueA1 == 0)
{
if(BassHit == false)
{
Keyboard.write(98);
BassHit = true;
//Use timer here to delay this part of the system
BassHit = false;
}
}
Thanks.
You can use the millis() function, something similar to the following code:
if(ButtonPress==true){
time=millis() //time was previously declared as unsigned long
if(time>=5000){ //5000 = 5 sec
ButtonPress==false
}
}
It will not stop the arduino loop as dealy() does.
More info: http://playground.arduino.cc/Code/AvoidDelay
Perhaps you are trying to de-bounce the button. I usually do this in the main loop, and expect 5 consecutive "pressed" reads before I say the button is really pressed, something like this:
int button1PressedCount = 0;
int debounceCounter = 5; // Number of successive reads before we say the switch is pressed
boolean buttonPressed = false;
int inputPin1 = 7;
void setup() {
// Grounding the input pin causes it to actuate
pinMode(inputPin1, INPUT ); // set the input pin 1
digitalWrite(inputPin1, HIGH); // set pin 1 as a pull up resistor.
}
void loop()
{
// Some code
// Check button, we evaluate below
checkButton();
// Some more code
}
void checkButton() {
if (digitalRead(inputPin) == 0) {
// We need consecutive pressed counts to treat this is pressed
if (button1PressedCount < debounceCounter) {
button1PressedCount += 1;
// If we reach the debounce point, mark the start time
if (button1PressedCount == debounceCounter) {
// Button is detected as pressed!
buttonPressed = true;
}
}
} else {
if (button1PressedCount == debounceCounter) {
// We were pressed, but are not any more
buttonPressed = false;
}
button1PressedCount = 0;
}
}
Also it seems using an analogue input with a check if the analogue value is exactly equal to 0 might be a bit sensitive in noisy environments. This is why I use a digital input and the internal pull up resistor.

Display response time seems too slow on simple functions

I have written an application in C using GTK 2.0 for a touchscreen panel with an ARM processor running debian linux. It is a very basic application that presents a few buttons (event boxes) on screen that can be clicked. On one page, I have 4 fields to present a "list" that can be scrolled through by clicking an up arrow and a down arrow (also event boxes). My function (code below) for the scrolling is very basic...it just updates each field with the next item from the array. Everything works fine, but the problem I am seeing is that if you repeatedly click the scroll button a little too quickly, it jumps ahead a few list items too far. My guess as to what is happening is that, when clicking too fast, the counter advances faster than the screen can update, so that by the time you click again it is actually updating with the then too-high counter. I wouldn't be concerned if it only happened when clicking REALLY fast, but I think the slow response seems way out of line for such a simple function repeating at a reasonably quick rate.
I'm hoping maybe someone has some input on something I might be missing in regards to screen refreshes with GTK?
Thank you in advance for any thoughts or advice!
Here is my code for my "volume-up" function and "scroll-up" function, both having the same problem. There are corresponding "scroll-down" and "volume-down" functions with the same issue:
static void sr_vol_up_clicked (GtkWidget *fakewidget, GdkEvent *fakeevent, gpointer number)
{
g_timer_start(lock_timer);
gtk_image_set_from_file (GTK_IMAGE(sr_vol_up_button),"./images/Admin/navigation_up_arrow_DOWN.png");
if (sr_current_level < 100)
{
sr_current_level = sr_current_level + 1;
gtk_label_set_text (GTK_LABEL(sr_current_level_label), (g_strdup_printf("%i", sr_current_level)));
set_sr_volume(sr_current_level);
}
gtk_image_set_from_file (GTK_IMAGE(sr_vol_up_button),"./images/Admin/navigation_up_arrow_UP.png");
}
And the other:
static void scroll_show_up ()
{
g_timer_start(lock_timer);
if (show_scroll_count > 0)
{
if (show_one_displayed - 1 < 0)
{
show_one_displayed = (show_loop_list->len -1);
}
else
{
show_one_displayed = show_one_displayed - 1;
}
gtk_label_set_text (GTK_LABEL(upcoming_show_1_label), get_show_name((char *)g_ptr_array_index(show_loop_list, show_one_displayed)));
if (show_two_displayed - 1 < 0)
{
show_two_displayed = (show_loop_list->len -1);
}
else
{
show_two_displayed = show_two_displayed - 1;
}
gtk_label_set_text (GTK_LABEL(upcoming_show_2_label), get_show_name((char *)g_ptr_array_index(show_loop_list, show_two_displayed)));
if (show_three_displayed - 1 < 0)
{
show_three_displayed = (show_loop_list->len -1);
}
else
{
show_three_displayed = show_three_displayed - 1;
}
gtk_label_set_text (GTK_LABEL(upcoming_show_3_label), get_show_name((char *)g_ptr_array_index(show_loop_list, show_three_displayed)));
if (show_four_displayed - 1 < 0)
{
show_four_displayed = (show_loop_list->len -1);
}
else
{
show_four_displayed = show_four_displayed - 1;
}
gtk_label_set_text (GTK_LABEL(upcoming_show_4_label), get_show_name((char *)g_ptr_array_index(show_loop_list, show_four_displayed)));
show_scroll_count = show_scroll_count - 1;
}
}

How to update silverlight UI while processing

I went through several examples posted online but I cant answer my question.
I have my 'p' variable that is being increased by 1 in the for loop. I want the UI to display the progress of calculation (to show how 'p' is increasing from 0 to 1000000). I do the calculation on the separate thread and the I call dispatcher to update the ResultBox in UI. Example:
int p=0;
...
private void GO(object sender, System.Windows.RoutedEventArgs e)
{
new Thread(delegate()
{
DoWork();
}).Start();
}
void DoWork()
{
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 10000; j++)
{
p++;
this.Dispatcher.BeginInvoke(delegate { ResultBox.Text = p.ToString(); });
}
}
}
For some reason this doesn't work. However when I put Thread.Sleep(1) just before this.Dispatcher... it works as intended. Does it mean that the UI update (Dispatcher) is called too frequently therefore it freezes?
Is there any other way to do it?
Thank you
Why not bind a property to your TextBox and the update the property value instead of poking at the textbox directly?
Yes only doing p++ in your loop will not take much of time and inside silverlight, Dispatcher is nothing but a simple queue with delegates, and before silverlight can even update and process its UI, you are pumping too many values on the queue. Imagin what will happen if you keep on adding queue way to faster then the queue is dequeued, then eventually it will hit max limit as well. And eventually it will just stop. If your p++ is replaced with more time consuming task, then you may get good result.
You must know that our eye usually can see only updates of 30 fps, more then 30 updates per second will not be of any use at all, I will suggest your view update should be reduced to max 10 updates per second for best performance.
And for showing progress, I think 1 update per second is also enough. First always display updates very slowly, like
void DoWork()
{
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 10000; j++)
{
p++;
if((p % 1000)==0){
this.Dispatcher.BeginInvoke(delegate
{ ResultBox.Text = p.ToString(); });
}
}
}
}
Now you can increaes/decrease 1000 to some suitable multipler of 10 to adjust your visual update.

Resources