I need to have a web page wait for a few seconds before doing something. Let's say that for "security" reasons I can't use the Thread class, so I can't call its Sleep method (don't ask).
I McGyvered this solution:
DateTime foo = DateTime.Now.AddSeconds(5);
while (DateTime.Now < foo) {
/*noop*/
}
It did work in a Console application, and in a simple page I did just now. I have half a heart to use this but something lodged the darkest corners of my shadow self keeps telling me I am only paving the way to my own doom by doing this. I feel there is a catch to it, but I can't tell what it is.
Is it safe to use? Is it sane?
Try this:
Mutex m = new Mutex();
w.WaitOne();
m.WaitOne(TimeSpan.FromSeconds(5));
This is a hack of course. But your requirement is to not use Thread.Sleep.
Alternatively, call a web service that sleeps for 5 seconds. That way you at least don't burn CPU in your busy loop.
Related
I have a while loop that runs some code whilst a selctor is hidden i.e.
while(await page.locator('.list-empty').isHidden()) {
// do something
}
How can i add a timeout here so that //do something is delayed before running?
i want to do this as i am finding the code runs too quickly and selectors cant be found...
You can use page.waitForSelector for each selector you need to find, and it will wait for 30 seconds. Also, you can manage the amount of time it waits.
example- as i clicked on button , output window should come but it should be like blurred or wait for some time (like something is executing in background).. after some time window should be in activate mode.
could you help me to achieve this without using thread.sleep method ?
Then, you could use a stopwatch , set it for the amount of time you need and then disable all controls of your application(Winform?Silverlight?)
Then you just loop until the stopwatch as finished, or display some kind of Processing label.
While(stopwatch.IsRunning)
{
//Do nothing
}
BTW: This is a synchronous operation, if there's something the thread needs to do while user input is on hold you can't use that.
This may be a bit of a beginners question, but I can't for the life of me figure it out.
I'm using flex to develop a GUI for a large project, specifically a status bar along the bottom. Within my StatusBar class is a ProgressBar, which other classes doing work can tell to update(change bar completion and label) as they progress. The problem I'm encountering is that flex won't update whats shown on the screen until it's too late, for example
ProgressBar initialized, 0% done
some class sets the ProgressBar to be 12% done
some class does some work
some class sets the ProgressBar to be 56% done
Whats happening is the 12% done is never displaying, it just hangs at 0% during the work, then skips right to 56% done. I've tried to understand the lifecycle of a flex component (invalidation and validation), and I think I understand it and am applying it correctly, but it's not working at all. I need to tell flex to redraw my StatusBar (or at least the ProgressBar within) after some class sets it to be 12% done, but before some class starts doing its work. How do I do this?
As mentioned in other answers, the flash player is single threaded, if you don't break up your work into discrete chunks that can be executed in separate "frames", you're going to see jumps and stutters in the ui, which is effectively what you're seeing.
If you really must see that 12% message, then it's not enough to invalidate the display list, as the display list isn't getting a chance to update until after the 56% work has completed, you must explicitly interrupt the natural event cycle with a call to validateNow() after your message has been set.
This however is not the best way to do things if performance is of concern. You might get by with judicial usage of callLater() to schedule each chunk of work in turn, as this will allow the player to potentially complete a frame cycle (and update the display list) before attempting the next step in your process.
Glenn,
That is not at all how the threading in Flex works whatsoever. Like many UIs it has a message pump on the main UI thread (they do it in frames). When you call callLater() it places the passed in function pointer at the end of the message pump queue (on the next frame) and returns immediately. The function then gets called when the message pump has finished processing all of the messages prior (like mouse clicks).
The issue is that as the property change causes UI events to be triggered, they then place their own messages on the pump which now comes after your method call that you placed there from callLater().
Flex does have multiple threads but they are there for Adobe's own reasons and therefore are not user accessible. I don't know if there is a way to guarantee that a UI update will occur at a specific point, but an option is to call callLater a number of times until the operation occurs. Start off with a small number and increase until the number of iterations produces the result you want. Example:
// Change this to a number that works... it will probably be over 1, depending on what you're doing.
private const TOTAL_CALL_COUNT:int = 5;
private var _timesCalled:int = 0;
//----------------------------------------------------------------
private function set Progress( progress:int ):void
{
progressBar.value = progress;
DoNextFunction();
}
//----------------------------------------------------------------
private function DoNextFunction():void
{
if( _timesCalled >= TOTAL_CALL_COUNT )
{
_timesCalled = 0;
Function();
}
else
{
_timesCalled++;
callLater( DoNextFunction );
}
}
Try calling invalidateDisplayList() after each changes to your progress bar. Something like :
Class StatusBar
{
public function set progress(value:uint):void
{
progressBar.value = value;
progressBar.invalidateDisplayList();
}
}
Flex has an invalidation cycle that avoid screen redrawing everytime a property changes. As an example, if a property's value changes 3 times in a single frame, it will render only with the last value set. You can force a component to be redrawn by calling invidateDisplayList() which means updateDisplayList will be immediatly executed instead of waiting the next frame.
Actionscript in Flash player, like Javascript in the browser, is pseudo-multithreaded. That is, they're single threaded, but they have multiple execution stacks. This means you can't "sleep" in a particular thread, but you can spawn a new execution stack that gets deferred until a later time. The flex way of doing this is the "callLater" function. You can also use the setTimeout/setInterval functions. Or you can use a timer object built into the flash player. Or even "ENTER_FRAME" event listener. All of these will essentially allow you to do what you need, if I'm correct about the cause of your problems.
It sounds like you have one "thread" doing most of your work, never stopping to allow other execution stacks (threads*) to run.
The problem could be what PeZ is saying, but if that doesn't help, you might want to try some deferred calls for worker classes. So your process might look like this now:
Progress initialized.
Do some work.
Update progress bar to 12. (invalidate display list)
setTimeout(doMoreWork, 100);
Update progress bar to 52.
(if your worker is a UIcomponent, you can use uicomp.callLater(...), otherwise, you need to use setTimeout/timers/enter_frame for pure AS3 classes).
Sometimes its necessary set to zero before assign another value.
progressBar.setProgress(0, progressBar.maximum);
progressBar.setProgress(newValue, progressBar.maximum);
I'm using Flash Builder 4.6 and I also have a problem for the display of my progress bar. I open a new window where I start a new multiloader class (39 Mo of content). The new window is opened in background and the main window display a progress bar until the multiloader class has finished his work. However the opening window is blocking the animation of my main window. I know it's not the multiloader class cause I saw it running correctly.
But I will try to find some new ways of doing it.
The main purpose of my post is the complexity adobe has build around flash.
When you seek ressources for your own application or answers for your questions, it's a real pain to find the good ressource. There is a total mix up (at adobe side and at user side) between AS3, Flex, Flash CS, Flash Builder, AiR, ... If you try to develop in AS3, you will find that some examples won't work for you because it is not implemented in your SDK. You have more and more forums giving you the "best practice" or ironic answers based on experiences on different developping platform.
By example, just here above, I see progressBar.value = value; With my experience, I can say that in Flash Builder 4.6, this property is read-only. But It might be a custom class made by the user but who can tell.
Is there any way to halt execution in ActionScript, such as a sleep() method?
I know that there is a setTimeout() method, but setTimeout() just sets up an event for deferred execution.
No. There is no sleep. Sorry.
See my answer here for options: ActionScript: pushing a closure onto the event stack?. It doesn't talk about sleeping, but I tried to provide an overview of deferred function calling.
You need to think in terms of not sleeping. Actionscript is not that kind of language. Because the flash player alternates between frame renders and code execution, sleeping in the code is always a bad idea, which is why there is no method to do it.
Having said that, you could achieve this by using the blocking method ExternalInterface.call, and in Javascript executing a blocking method (like XHR request).
Absolutely idiotic though, so don't do it.
Perhaps what you need is a Timer.
There's no way to pause all execution of an application as in PHP, but there are workarounds (unless you set a breakpoint or create a runtime error on purpose, don't think that's what you meant). Probably this is because usually flash applications are meant to execute all the scripts in less than one "frame".
It's common to be able to "pause" the animations of a website when the user unfocus it. This can be made by listening to Event.DEACTIVATE and then remove the ENTER_FRAME listeners and kill all ongoing processes.
You could also create a central EventDispatcher to replace the internal ENTER_FRAME, this way you seamlessly control speed of execution as well as pausing / resuming (won't stop executing scripts, nor asynchronous handlers such as loaders etc. though).
Yes, there is, though be aware of the 15 second script timeout. ( You can change that 15 second script timeout in the Publish Settings... )
I've found in the past that if you're looking for this functionality, you're doing something wrong :)
Whatever you're trying to accomplish is probably calling for an Event listener instead.
//adding this ENTER_FRAME event listener just to show that the script pauses for one
// second before the first frame executes
addEventListener( Event.ENTER_FRAME, onFrame );
function onFrame( event:Event ):void {
trace( "first frame occurs after pause of", getTimer() + " ms" );
removeEventListener( Event.ENTER_FRAME, onFrame );
};
var startTime:int = getTimer();
var pauseTime:int = 1000;
while( ( getTimer() - startTime ) < pauseTime ) {
//do nothing... we're effectively pausing here...
}
Is there a way to make synchronous calls using RemoteObject in Flex?
All IO in Flex is asynchronous. The typical pattern to deal with this is to use an AsyncResponder. For instance:
var t:AsyncToken = remoteObject.methodCall();
t.addResponder(new AsyncResponder(resultEvent, faultEvent));
think twice when u want it to be synchronous.
Do u know what synchronous mean? it will FREEZE your application until it receive data. Unless u are pretty sure that your remote calling can receive return value immediately (super fast network connection).
if your function call depends on each other, i would suggest you implement a state machine. e.g.
after 1st async call, your state becomes STATE_1, and your next function call will check on this state variable, to decide next move (ignore the current call or carry on).
my 2 cents.
If you want synchronous behavior, just add a wait after you make the call.
EDIT: I've added code for the chaining behavior I was talking about. Just replace the result handler each subsequent time you call the remoteObject.
...
remoteObject.function1(...);
...
private var resultHandler1(event:ResultEvent):void
{
...
remoteObject.removeEventListener(resultHandler1);
remoteObject.addEventListener(ResultEvent.RESULT, resultHandler2);
remoteObject.function2(...);
}
private var resultHandler2(event:ResultEvent):void
{
...
}
I achieved the same in two ways: First, as said above the use of state machines. It may get tricky at times. Second, the use of command queues - I think this is the best way to do it... but the downside is that the UI may not be very reflective in this time.
you should perhaps try and make one request with with all the data u want to be recieved synchronous and then make the different classes that need data listen to the correct data for that class.
ex:
// request
remoteobject.GetData();
// on received request
private function receivedData(evt:ResultEvent):void
{
for each (var resultobject:ResultObjectVO in evt.result)
{
var eventModel:Object;
var event:DataEvents = new DataEvents(resultobject.ResultType);
event.data = eventModel;
eventdispatcher.dispatchEvent(event);
}
}
Something like this. Hopes this helps.
No, why would you wish to do that anyway.
Flex makes things asynchronous so that the user isn't forced to sit and wait while data is coming back.
It would be a very poor user expereince if each time an app requested data the user had to wait on it coming back before anything else could happen.
from comment
No you don't need synchronus behaivour. If you're making say 2 calls and call 2 comes in before call 1, but 2 relies on the data inside 1 then you're left with either don't fire off event 2 till 1 comes back (this will slow down your app - much like synchronus events) or implement a way to check that event 1 has come back in event 2's handler (there are many ways you could do this).
If you're firing off many events then why not have a wrapper class of some description that tracks your events and doesn't do anything on the responses until all events are back.
You can use the AsyncToken to keep track of individual requests, so if you are firing of loads at once then you can find out exaclty whats come back and whats not.
You all are somehow mistaken or not using flex from adobe, if you send 2 calls to the server, no matter if each has an individual resquestObject the second one will ONLY be returned after the first one finish, even if the second one takes 1 milisecond to process. Just try the fibonnaci 1/40 example.
Maybe if you call a synchronous XMLHttpRequest calling JavaScript on Flex, you can do this.