Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting low user activity and checking email on background

I'm writing an application that must do some things in background: check emails and parse them to inject some data in a database, and connect to a web service to check status for some asynchronous operations.

Right now, my solution is a simple timer that performs these operations on a predefined schedule: email every five minutes, and web service checks every minute (but these are only performed if there is pending activity, so most of the time this does nothing.)

Right now I'm not using a thread for this (I'm early in the development stage.) But my plan is to create a background thread and let it do the work offline.

Couple of questions:

  1. I plan to control everything in the timer(s). Set up a global variable (rudimentary "locking",) start the thread. If the "lock" is already set, ignore it. The thread cleans it up on termination. Should I use a more robust locking / queue mechanism for my threads? (I already have OmniThread installed)
  2. How can I run a thread with low priority? I don't want the application to feel sluggish when the background thread is performing data insertion or networking.
  3. Is there a clean way to verify for user activity and start this thread only when the user is not busy at the keyboard / mouse?

Please have in mind that I'm not experienced with threads. I wrote an FTP sync application once so I'm not a complete newbie, but that was long time ago.

like image 993
Leonardo Herrera Avatar asked Mar 13 '12 15:03

Leonardo Herrera


2 Answers

For part 3 of your question, the Windows API has a GetLastInputInfo function which should return information about the last time the user did something. It even says it's "This function is useful for input idle detection". I did plan to use this for something myself, but haven't had a chance to test it.

Edit: Delphi implementation link

like image 82
Kieran Avatar answered Sep 19 '22 00:09

Kieran


  1. I plan to control everything in the timer(s). Set up a global variable (rudimentary "locking",) start the thread. If the "lock" is already set, ignore it. The thread cleans it up on termination. Should I use a more robust locking / queue mechanism for my threads? (I already have OmniThread installed)

I wouldn't bother with the Timer at all. Make your thread's loop look like this, and you'll have your delays. You will NOT need a lock because there's only one thread, it will not sleep until the previous job is over.

procedure YourThread;
var N: Integer;
begin
  while not Terminated do
  begin
    // Figure out if there's a job to do
    // Do the job

    // Sleep for a while, but give the thread a chance to notice
    // it needs to terminate.
    for N := 1 to 500 do
      if not Terminated then
        Sleep(100);
  end;
end;
  1. How can I run a thread with low priority? I don't want the application to feel sluggish when the background thread is performing data insertion or networking.

Don't bother. You can easily use SetThreadPriority but it's not worth the trouble. If your background thread is waiting for I/O (networking), then it will not consume any CPU resource. Even if your background thread works full-speed, your GUI will not feel sluggish because Windows does a good job of splitting available CPU time among all available threads.

  1. Is there a clean way to verify for user activity and start this thread only when the user is not busy at the keyboard / mouse?

Again, why bother checking for user activity? Checking for email is network (ie: I/O) bound, the thread checking for email will mostly be idle.

like image 21
Cosmin Prund Avatar answered Sep 18 '22 00:09

Cosmin Prund