What is the RIGHT way to do multithreading in Azure

I have an Azure application that requires 3 uniquely unique tasks to run as lengthy processes. I could easily deploy 3 Worker Roles, but it would cost 3 times what I would have to spend, given how simple the tasks are. I would like to run each task in its own thread, since each task is different from the time it takes to complete, and how often it takes to complete.

Given this scenario or even the generic multi-threaded Azure scenario, what is the best way you know that each task runs independently?

A few considerations I would suggest are as follows:

  • Keep the processor busy (not always possible with EventWaitHandles ..?).
  • Uses the most advanced frame utilities (i.e. TPL or PLINQ).
  • Graceful shutdown and reboot in the event of a fatal exception.

Thanks for the suggestions, links or sample code.

EDIT

Here's what I decided - given that the code is tied to an Azure cloud, the self-healing option seems the most appropriate. This approach aims at collecting a collection of threads and delegating their work to various โ€œunits of workโ€.

That's how he stuck together. First, a simple class to bring together diverse workers.

public class ThreadWorker { internal void RunInternal() { try { Run(); } catch (SystemException) { throw; } catch (Exception) { } } public virtual void Run() { } public virtual void OnStop() { } } 

Next, the code is to keep the thread chain indefinitely. This includes a list of threads, a list of "workers" (one per thread) and an infinite loop that checks the status of each thread for a given interval.

Note that the exception that terminates the thread does not break other threads. If an unhandled exception occurs, the thread will be restarted the next time the event listener is called.

 private readonly List<Thread> _threads = new List<Thread>(); private readonly List<ThreadWorker> _workers = new List<ThreadWorker>(); private EventWaitHandle EventWaitHandle = new EventWaitHandle(false, EventResetMode.ManualReset); public override void Run() { foreach (var worker in _workers) { _threads.Add(new Thread(worker.RunInternal)); } foreach (var thread in _threads) { thread.Start(); } while (!EventWaitHandle.WaitOne(500)) { // Restart any threads that have stopped running for (var i = 0; i < _threads.Count; i++) { if (_threads[i].IsAlive) { continue; } _threads[i] = new Thread(_workers[i].RunInternal); _threads[i].Start(); } EventWaitHandle.WaitOne(2000); } } 

Simple enough - the main thread (in this case, the Run method of the Azure working role) blocks half a second between checks on the active list of threads. Completed threads are restarted, and the host thread is then blocked for 2 seconds before checking again that the workflows are working.

Adding workers is as simple as adding a list of classes that inherit from the ThreadWorker base class.

 _workers.Add(new SomeWorker()); _workers.Add(new AnotherWorker()); 

And finally, specific workers:

 public class SomeWorker: ThreadWorker { public override void Run() { while (true) { // Do your long running work here. Thread.Sleep(2000); // Take a breather - not necessary. } } } public class AnotherWorker: ThreadWorker { public override void Run() { while (true) { // Do your long running work here. } } } 
+4
source share
4 answers

I think this is a fairly common scenario - in an ideal world, one job per role, but for cash reasons (and environmental reasons too!) It is best to combine them into one role.

I personally do not think there is a LAW - there are several options, and you need to choose the one that best suits your current requirements for your application:

+3
source

Your problem is not a unique problem, but simply a classic thread on a single processor. (If you use several processors in one instance, you can also run separate instances, this is the same cost).

I am a big fan of TPL, he solved many of the usual problems for you, so I think I agree with that.

+1
source

Make each task a separate .exe and release them from the WorkerRole class. From there, monitor processes for unexpected termination (Process.WaitForExit ()) and disable them again. (But think about what happens if one process crashes all the time - it will use 100% CPU start, crash and start again. Perhaps you can use exponential shutdown for this.)

I assume that you will only have one role instance for these three tasks, in which case you should also think about how your system will handle an accidental shutdown and restart of Azure due to a hardware failure or something else. (With multiple instances, it is very unlikely that they will all crash together.)

0
source

I will start a topic for each of these long life tasks.

This is actually what I am doing in one of my roles: Running multiple work roles on a single instance

I load types and call the Run method in a separate thread.

0
source

Source: https://habr.com/ru/post/1347639/


All Articles