Background thread, async and GUI (dlangui)
Ali Çehreli
acehreli at yahoo.com
Wed Jul 6 23:17:22 UTC 2022
On 7/6/22 02:26, Bagomot wrote:
> 1) How to make asynchronous HTTP requests with curl in order to receive
> progress and status? And how do you know that the request is completed?
I don't know how dlangui or others automate this but I had fun writing
the following program that uses std.concurrency and std.net.curl:
> 3) My application must perform some work in a separate thread (I do this
> through inheritance of the worker from core.thread.Thread, is that
> correct?).
core.thread.Thread is low level. I would consider std.parallelism and
std.concurrency first. (I use the latter for message passing in the
program below.)
import std.concurrency;
import std.net.curl;
import std.conv;
import std.stdio;
import std.algorithm;
import std.range;
import std.format;
// Signifies that the main thread requests the getter to stop
// serving. (Not used here.)
struct Done {}
// Represents download progress.
struct Progress {
size_t downloaded;
size_t total;
}
// Represents a URL
struct Url {
string value;
}
// The thread entry point for the getter
void getterFunc() {
receive(
(Done _) {
// Not used here but this is for clean termination.
return;
},
(Url url) {
// Received a URL to get.
auto http = HTTP(url.value);
// std.net.curl.HTTP will call this delegate with progress
// information...
http.onProgress((size_t dl, size_t dln, size_t ul, size_t uln) {
if (dl != 0) {
// ... and we will send it along to the main thread.
ownerTid.send(Progress(dln, dl));
}
return 0;
});
// std.net.curl.HTTP will call this delegate with
// downloaded parts...
http.onReceive((ubyte[] data) {
// ... and we will send it along to the main thread.
ownerTid.send((cast(char[])data).to!string);
return data.length;
});
// Everything is set up. Let's do it.
http.perform();
},
);
}
void main() {
auto getter = spawnLinked(&getterFunc);
getter.send(Url("dlang.org"));
string result;
bool done = false;
while (!done) {
receive(
(LinkTerminated msg) {
// (This may or may not be expected.)
stderr.writefln!"The getter thread terminated.";
done = true;
},
(Progress progress) {
writeln(progress);
if (!result.empty &&
(progress.downloaded == progress.total)) {
done = true;
}
},
(string part) {
result ~= part;
},
);
}
writefln!"Downloaded %s bytes:\n%s"(result.length, result);
}
Ali
More information about the Digitalmars-d-learn
mailing list