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