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.
Related
I'm trying to build an NES emulator using winit, which entails building a game loop which should run exactly 60 times per second.
At first, I used std::thread to create a separate thread where the game loop would run and wait 16 milliseconds before running again. This worked quite well, until I tried to compile the program again targeting WebAssembly. I then found out that both winit::window::Window and winit::event_loop::EventLoopProxy are not Send when targeting Wasm, and that std::thread::spawn panics in Wasm.
After some struggle, I decided to try to do the same thing using task::spawn_local from one of the main asynchronous runtimes. Ultimately, I went with async_std.
I'm not used to asynchronous programming, so I'm not even sure if what I'm trying to do could work.
My idea is to do something like this:
use winit::{window::WindowBuilder, event_loop::EventLoop};
use std::time::Duration;
fn main() {
let event_loop = EventLoop::new();
let _window = WindowBuilder::new()
.build(&event_loop);
async_std::task::spawn_local(async {
// game loop goes here
loop {
// [update game state]
// [update frame buffer]
// [send render event with EventLoopProxy]
async_std::task::sleep(Duration::from_millis(16)).await;
// ^ note: I'll be using a different sleep function with Wasm
}
});
event_loop.run(move |event, _, control_flow| {
control_flow.set_wait();
match event {
// ...
_ => ()
}
});
}
The problem with this approach is that the game loop will never run. If I'm not mistaken, some asynchronous code in the main thread would need to be blocked (by calling .await) for the runtime to poll other Futures, such as the one spawned by the spawn_local function. I can't do this easily, since event_loop.run is not asynchronous.
Having time to await other events shouldn't be a problem, since the control flow is set to wait.
Testing this on native code, nothing inside the game loop ever runs. Testing this on Wasm code (with wasm_timer::Delay as the sleep function), the game loop does run, but at a very low framerate and with long intervals of halting.
Having explained my situation, I would like to ask: is it possible to do what I'm trying to do, and if it is, how would I approach it? I will also accept answers telling me how I could try to do this differently, such as by using web workers.
Thanks in advance!
I am coding a Task in a plugin to nopcommerce. The Task must download a catalogue from a website (https://data.icecat.biz/export/level4/). If the download fail for some reason, I want my program to wait for a minute and then try again a couple of times.
e.g
while(notTiredOfWaiting)
{
try{
// my download stuff here
return data;
}
catch(Exception e)
{
Thread.Sleep(60000);
// or
Task.Delay(60000);
}
}
My problem is that nopcommerce is some kind of blackbox, which starts and run my task. The "easy" solution is to use Thread.Sleep(), but I don't know if any other important processes runs on the same thread. I have tried Task.Delay(), but it doesn't seem to work in my implementation.
I known that Thread.Sleep versus Task.Delay() is a hot topic on SO, but I am asking for a specific answer for what is best practice in nopCommerce.
Edit.
The task is using IScheduleTaskService.
I think the best option for the retrying operation is a System.Threading.Timer, you doesn't need to worry about nopcommerce threading behaviour and you let .net to manage the threading stuff, you can use something like:
void Retry(){
if(notTiredOfWaiting)
{
var timer = new System.Threading.Timer((cb) => { Retry() }, null, 60000, 0);
}
}
Icecat is a quite big catalog, so I'm not surprised you're getting trouble with it.
You could change your algorithm to something like:
Set your task to run at short intervals, for instance every 15 minutes.
Try to acquire a lock at the beginning of the task; if the lock is taken then the previous task is still running, just return without processing.
If the lock is not taken, acquire the lock, and check the last time the process ended. If enough time has passed, run your task (1 day, 1 week, or the amount of time you may need between downloads). You need to store the last time somewhere: you can use one of your own tables, or a custom setting would do just fine.
If the task was successful, save the new ending time.
Release the lock.
Maybe you would like to add a limit to the times you retry. And some logging.
// Sample pseudocode
if (Monitor.TryEnter(lockObj)) {
try {
if (EnoughTimeHasPassed())
{
DownloadIcecat();
SaveLastFinishingTime(now);
}
}
finally { Monitor.Exit(lockObj); }
}
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.
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.
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...
}