In short, Parallel.Async accepts an anonymous method, normal method or procedure (all of them must be without parameters) and executes it in a background thread. That’s all.
Parallel.Async( procedure begin MessageBeep($FFFFFFFF); end,For slightly more complicated scenarios, you can also provide a second parameter, which is an anonymous method, normal method or procedure (again without any parameters) that will execute after the background task is completed. This second part of code executes in the context of the main thread so you can interact with the VCL from it.
A new demo 46_Async demonstrates this.
procedure TfrmDemoParallelAsync.btnAsyncClick(Sender: TObject); begin btnAsync.Enabled := false; Parallel.Async( procedure begin // executed in background thread Sleep(500); MessageBeep($FFFFFFFF); end, procedure begin // executed in main thread btnAsync.Enabled := true; end ); end;Clicking the button disables it and executes background task. Method btnAsyncClick then immediately exits and your app can proceed executing other code.
After half a second sleep, MessageBeep is executed in a background thread. Background task then terminates. At the end, termination code that re-enables button btnAsync is executed in the main thread.
Simple, but effective.
The way the code snippet is written it returns after half a second, instead of 5.
ReplyDeleteI like this a lot. A no fuss method for running background SQL queries, long calculations, waiting for network transfers and the list goes on and on:)
Best regards,
Ajasja
Half a second, of course! Fixed the text, thanks!
ReplyDeleteNice to see this, Primoz.
ReplyDeleteThis piece of code is very similar (in the intent) to a very useful class in the Android SDK:
http://developer.android.com/reference/android/os/AsyncTask.html
Thanks for your work.
Not sure why I can't pass the second parameter - all I get is "There is no overloaded version of Async that can be called with these arguments", I even tried the snippet above..
ReplyDelete@Imagine, the syntax has changed. Read more about it here: http://www.thedelphigeek.com/2011/07/life-after-21-async-redux.html
ReplyDeleteGabr,
ReplyDeleteBeen using this particular construct. Great stuff - except that if the main window is being destroyed when calling, for example, the OnFinish handler may try to access an invalid object. How can I fix this? (just asking if the control is null doesn't work because it may catch right in the middle of calling a destructor, it seems)
I would forbid form destruction while Async is in progress. You can do that by handling the OnCloseQuery event.
Delete