3

I'm trying to create an worker service that polls database every few seconds for emails. Emails are passed to a priorityQueue and from there sent via Rest API to external provider. I would like to also implement some kind of limit on number of threads used by queue.

So here is my ExecuteAsync from BackGroundService:

 protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) {/*Poll email database*/ var emails = await _emailRepository.GetEmailsToSend(); foreach (var email in emails) /*Queue downloaded emails*/ _queue.QueueEmail(email); await Task.Delay(_emailOptions.PollTime, stoppingToken); } } 

And here is my BackgroundEmailQueue to which emails are given:

public class BackgroundEmailQueue : IBackgroundEmailQueue { private readonly ILogger<BackgroundEmailQueue> logger; private readonly ConcurrentPriorityQueue<EmailToSend> queue; private readonly SemaphoreSlim signal; private event Action EmailQued; public BackgroundEmailQueue(ILogger<BackgroundEmailQueue> logger) { this.queue = new ConcurrentPriorityQueue<EmailToSend>(); this.signal = new SemaphoreSlim(5, 5); this.EmailQued += OnEmailQued; this.logger = logger; } public void QueueEmail(EmailToSend email) { if (email == null) return; queue.Add(email); EmailQued.Invoke(); } private async void OnEmailQued() { await signal.WaitAsync(); var email = queue.Take(); await Task.Run(async () => { .... /*sending email*/ } ); signal.Release(); } } 

This solution works as intended

My problem is:

Was using the event to fire new thread good solution?

Is there a better way to do this?

11
  • You can use Parallel.ForEach where we will have the total control of number of max async threads. stackoverflow.com/questions/9538452/… Commented Aug 10, 2020 at 8:31
  • But when or where do you fire the Parallel.ForEach, service polls the database every few seconds. The queue can have thousands of emails in one moment and none few minutes later. Commented Aug 10, 2020 at 8:33
  • Have you considered using a BlockingCollection? Perhaps Google for blockingcollection process in parallel? Commented Aug 10, 2020 at 8:34
  • If you want code to be reviewed than codereview.stackexchange.com might be a better place. Commented Aug 10, 2020 at 8:36
  • To mjwills: well, I dont really have a problem with collection itself. I need an priority queue becouse emails have an priority. Whole point of the code is to solve peaks when thousands of emails are added to database. What my problem is: I dont know how to efficiently start up those threads doing the sending or where to start them up, or when. Commented Aug 10, 2020 at 8:42

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.