DFL background tasks

thedeemon via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jun 8 00:22:00 PDT 2015


A more general and proper approach is to use message passing from 
std.concurrency. With DFL it looks like this: you spawn() a 
thread and don't pass any GUI controls to it, just thisTid 
(identifier of your main UI thread). In that worker tread when 
you've got some data to show in the UI (be it end result of just 
some status update) you use tid.send(...) and send the data in 
appropriate messages (defined as separate structs or classes). In 
the main UI thread you've got a Timer running that checks whether 
there are any messages in the main thread's mailbox and process 
them there.

Here's an example from a real DFL project:
https://bitbucket.org/infognition/undup/src/e8d295b89bc76545860e38a8c9ee171c86f3c84c/newscan.d?at=default#cl-200

OnStart() is a button callback. It does some quick UI updates and 
spawns a thread, passing relevant data and thisTid:

   worker = spawn(&makeScan, fname, hdr, thisTid);

(makeScan is a function with some long running operation, it's 
defined in another module)

There is also a timer set up when a form is created, and in the 
timer function OnTimer() there is a check for new messages via 
receiveTimeout(dur!"msecs"(0).

while(receiveTimeout(dur!"msecs"(0), &RcvMsgNumOfDirs, 
&RcvMsgScanning, &RcvMsgDone)) {}

Important part here is to make it non-blocking, it should not sit 
here waiting for new messages, otherwise UI will not be 
responsive.

And RcvMsgNumOfDirs, RcvMsgScanning, RcvMsgDone are functions 
that react to corresponding messages sent from the worker thread. 
They work in the UI thread, of course.


More information about the Digitalmars-d-learn mailing list