Background thread, async and GUI (dlangui)

Ali Çehreli acehreli at yahoo.com
Thu Jul 7 18:26:15 UTC 2022


On 7/6/22 16:17, Ali Çehreli wrote:

 > I would consider std.parallelism

And it looks more natural with a std.parallelism.Task:

struct Progress {
   size_t percent_;

   void set(size_t downloaded, size_t total) {
     if (total != 0) {
       import core.atomic: atomicStore;

       const value = cast(size_t)(float(downloaded) / float(total) * 100);
       atomicStore(percent_, value);
     }
   }

   size_t get() const {
     import core.atomic: atomicLoad;

     return atomicLoad(percent_);
   }
}

struct Request {
   string url;
   string result;
   Progress progress;
}

void download(Request * request) {
   import std.net.curl: HTTP;

   auto http = HTTP(request.url);

   http.onProgress((size_t dl, size_t dln, size_t ul, size_t uln) {
       if (dl != 0) {
         request.progress.set(dln, dl);
       }
       return 0;
     });

   http.onReceive((ubyte[] data) {
       request.result ~= (cast(char[])data);
       return data.length;
     });

   http.perform();
}

void main() {
   import std.parallelism : task;
   import std.stdio: writefln;

   auto request = Request("dlang.org");
   auto downloadTask = task!download(&request);
   downloadTask.executeInNewThread;

   foreach (i; 0 .. 10) {
     writefln!"Doing work on the side (%s)"(i);
     writefln!"Checking download progress: %s%%"(request.progress.get());

     import core.thread;
     Thread.sleep(100.msecs);
   }

   // Now we need the result before continuing:
   downloadTask.yieldForce();

   writefln!"Downloaded %s bytes:\n%s"(request.result.length, 
request.result);
}

Ali



More information about the Digitalmars-d-learn mailing list