0

I am working on an application that receives "jobs" to work on, and could only run 3 jobs in parallel (say 3 is a configurable number).

Here's how the flow looks like:

  1. A job is received somehow (not really relevant to the point)
  2. A task is running that watches a queue of jobs and picks up the next one 2.a. The job is passed over to a ConcurrentExecutor class that we have created that can block the creation of an additional Task (which runs the "job" itself) using a semaphore, until the other tasks (if any) have finished.

At this point, the task that's being created in 2.a is an abandoned task, meaning that we are losing any exceptions that occur in that "job" task that we have spawned.

I am trying to find an elegant solution to managing the spawned tasks. I have thought of a simple list that I can add the Task to, after which I can remove the task from it once it's done (same location as when I release the semaphore one the task is done).

But then we have hit a roadblock, in the sense of how would we wait for the tasks to finish (to monitor their exceptions), AND in the same time wait for new jobs to pick up. Yep, we could create another thread to monitor these, but then we would have to Join to it as some point as well.

We have thought about only picking up the "failed" jobs using ContinueWith, and should there be anything in the list - that's an exception from the task, but that's also not very elegant.

I am hunting for an idea that would allow me to: a. monitor the queue and spawn new jobs b. monitor the current running jobs and catch their exceptions

Thanks!

MichaelEr
  • 75
  • 2
  • 8
  • What would you like to happen in case the abandoned task fails? It seems that it's a significant task, and the application can't really keep going if this task has suffered an unexpected error. Would you like to elevate a possible exception of this task to a fatal unhandled exception that will kill the app? – Theodor Zoulias Apr 17 '22 at 14:25
  • @TheodorZoulias Well in fact it can continue just fine, it's that I would like to be aware of what has happened there. I wouldn't want to kill the app in this case though. How would you go about raising an exception that will kill the whole app? and do you reckon I could leverage this to my needs that I have described. – MichaelEr Apr 18 '22 at 08:29
  • Michael you can elevate a task failure to a fatal error by awaiting the task in an `async void` delegate invoked on the `ThreadPool`: `ThreadPool.QueueUserWorkItem(async _ => await task);`. I have posted about this in this question: [Ensuring task execution order in ThreadPool](https://stackoverflow.com/questions/7192223/ensuring-task-execution-order-in-threadpool/69293021#69293021) – Theodor Zoulias Apr 18 '22 at 08:39
  • If you just want to be aware of the error, couldn't you just wrap your work in a `try`/`catch` block, and invoke the error-notification in the `catch`? – Theodor Zoulias Apr 18 '22 at 08:46
  • @TheodorZoulias The code block is wrapped in a try-catch block, although beside logging in the catch block there isn't much I can do to elevate it (beside using the method you have posted in your previous comment) – MichaelEr Apr 18 '22 at 12:13
  • To be honest I am still confused about what your are trying to achieve. So in case a task fails, do you want just a notification, or the termination of the app? Or maybe both (notification and then termination)? – Theodor Zoulias Apr 18 '22 at 12:21
  • @TheodorZoulias - Only a notification. The last thing I want is termination of the app – MichaelEr Apr 18 '22 at 13:44
  • And what's the problem with sending the notification in the `catch`? – Theodor Zoulias Apr 18 '22 at 14:06
  • @TheodorZoulias - A notification in the sense of logging is there, I thought of the case where somehow, the logger fails, and I would lose that message, since there's no one waiting on the task, sort of a 2nd layer of backup. – MichaelEr Apr 20 '22 at 08:06
  • 2
    In case the logger fails, how would you know? AFAIK most logging libraries guarantee that logging will never throw an exception, even if it fails. They provide custom mechanisms to detect a logging failure, and take some action upon it. But practically speaking, if you don't trust your logger it's probably time to search for a better one. – Theodor Zoulias Apr 20 '22 at 08:18

0 Answers0