Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

synchronize threads - no UI

I'm trying to write multithreading code and facing some synchronization questions. I know there are lots of posts here but I couldn't find anything that fits.

I have a System.Timers.Timer that elapsed every 30 seconds it goes to the db and checks if there are any new jobs. If he finds one, he executes the job on the current thread (timer open new thread for every elapsed). While the job is running I need to notify the main thread (where the timer is) about the progress.

Notes:

  1. I don't have UI so I can't do beginInvoke (or use background thread) as I usually do in winforms.
  2. I thought to implement ISynchronizeInvoke on my main class but that looks a little bit overkill (maybe I'm wrong here).
  3. I have an event in my job class and the main class register to it and I invoke the event whenever I need but I'm worrying it might cause blocking.
  4. Each job can take up to 20 minutes.
  5. I can have up to 20 jobs running concurrently.

My question is:

What is the right way to notify my main thread about any progress in my job thread?

Thanks for any help.

like image 259
UshaP Avatar asked Mar 17 '10 15:03

UshaP


People also ask

What does __ Syncthreads do?

More generally, __syncthreads() is a barrier primitive designed to protect you from read-after-write memory race conditions within a block.

How do you sync threads in C#?

We can use C# lock keyword to execute program synchronously. It is used to get lock for the current thread, execute the task and then release the lock. It ensures that other thread does not interrupt the execution until the execution finish.

Why is thread synchronization required?

Synchronization in java is the capability to control the access of multiple threads to any shared resource. In the Multithreading concept, multiple threads try to access the shared resources at a time to produce inconsistent results. The synchronization is necessary for reliable communication between threads.


2 Answers

You can also use lock to implement a thread-safe JobManager class that tracks progress about the different worker threads. In this example I just maintain the active worker threads count, but this can be extended to your progress reports needs.

class JobManager
{
    private object synchObject = new object();

    private int _ActiveJobCount;

    public int ActiveJobsCount
    {
        get { lock (this.synchObject) { return _ActiveJobCount; } }
        set { lock (this.synchObject) { _ActiveJobCount = value; } }
    }

    public void Start(Action job)
    {
        var timer = new System.Timers.Timer(1000);

        timer.Elapsed += (sender, e) =>
        {
            this.ActiveJobsCount++;
            job();
            this.ActiveJobsCount--;
        };

        timer.Start();
    }
}

Example:

class Program
{
    public static void Main(string[] args)
    {
        var manager = new JobManager();

        manager.Start(() => Thread.Sleep(3500));

        while (true)
        {
            Console.WriteLine(manager.ActiveJobsCount);

            Thread.Sleep(250);
        }
    }
}
like image 146
João Angelo Avatar answered Sep 21 '22 18:09

João Angelo


You can notify the main thread of progress through a callback method. That is:

// in the main thread
public void ProgressCallback(int jobNumber, int status)
{
    // handle notification
}

You can pass that callback method to the worker thread when you invoke it (i.e. as a delegate), or the worker thread's code can "know" about it implicitly. Either way works.

The jobNumber and status parameters are just examples. You might want you use some other way to identify the jobs that are running, and you may want to use an enumerated type for the status. However you do it, be aware that the ProgressCallback will be called by multiple threads concurrently, so if you're updating any shared data structures or writing logging information, you'll have to protect those resources with locks or other synchronization techniques.

You can also use events for this, but keeping the main thread's event subscriptions up to date can be a potential problem. You also have the potential of a memory leak if you forget to unsubscribe the main thread from a particular worker thread's events. Although events would certainly work, I would recommend the callback for this application.

like image 23
Jim Mischel Avatar answered Sep 17 '22 18:09

Jim Mischel