0

I'm trying to make a series of microservices and am currently working on a base class for them utilizing a .Net Core console app. The goal is to have the services, deployed as Docker containers, be able to monitor a source of information (Kafka, SQL, whatever) ,and then activate when they find their trigger. A dev should be able to just grab this base class and put their logic in place without having to worry about the logic triggering it or any other underlying service logic.

To do this I'm trying to utilize threading in the base class in a way that the user of the class doesn't have to deal with it but keeps the service responsive and able to monitor/respond to external commands (like the ability to get status, cancel a job, etc). Unfortunately it seems that Microsoft is trying to do away with System.Threading in .Net core, since I can start threads them but I can't stop them. This removes the ability to cancel/pause a job, which in turn removes the ability to shut down the service since I cannot stop the thread.

I've looked at Tasks, but they seem to be for web development. In fact most if not all information I've found about threading and microservices in .Net Core refers to making WebAPIs in ASP .Net. Other than that I really haven't found much information about how to use System.Threading now that every control other than .Start seems to have been removed.

I'm about to look at a system where I have the thread host a Task, then try using Task controls to see if I can cancel it and then have the thread just gracefully drop (similar to answer from here: dotnet core equivalent to Thread.Abort). This doesn't feel right, like I'm making a toothpick tower that can easily break, however I need to have the base service maintain control over the thread; I don't want myself or others to have to continuously check a token throughout their logic to see if the thread is supposed to be shut down.

Is there a better way of going about what I'm trying to do here? I've been looking for days but I keep running into the same stuff and it's all about how to make webapis utilizing Tasks, which is nothing like what I'm trying to do here; they pause the main logic rather than run independently. Guess it's an annoying bi-product of this "everything must be a website" frame of mind in the industry. Not sure if I'm missing something obvious by asking the wrong questions or if it's just going to be this odd of a job.

7
  • 3
    Task is a universal abstraction for a thread, it is not just useful in web apps. Commented Feb 17, 2020 at 19:25
  • Is there a way to set a task to run in the background and not disturb the flow of the main thread? I've not found how to do that yet, though I'm just getting started on using tasks. So far my code just stops and runs the task until completion, and it appears that async requires await to work, which means that my main thread would just be sitting at the await call. It doesn't appear to be independent like a thread is. Commented Feb 17, 2020 at 19:40
  • Using Thread.Abort is about as far from "graceful" as you can possibly get. It's the equivalent of taking the thread out into the forest and shooting it. There is a reason the task system is based on cooperative threading, it's the only safe route to go. Commented Feb 17, 2020 at 19:40
  • 1
    "Is there a way to set a task to run in the background and not disturb the flow of the main thread" -> just run the Task without await, if it's "hot". Id it's cold, you can use Task.Start (or Task.Run to create it as well) Commented Feb 17, 2020 at 19:41
  • 1
    Awesome, thanks Pac0, that worked. I don't know what I was doing differently that caused it to not work before. Previous attempts at creating a task variable and setting it to run just paused the main thread in place, waiting on the task to end, but this time using Task.Start worked. If you'd like to post this as the answer I'd be happy to accept it. Commented Feb 17, 2020 at 19:50

1 Answer 1

2

Task and await/async language features are a nice way to abstract threading, and are supposed to help exactly for what you wish for (keep the application responsive by using thread pool), whilst saving you the hassle of properly create and manage all those threads (not to mention catching exceptions during asynchronous execution).

As stated in comments, I think you should give it a try "properly" and then measure if it meets your performance objectives.

Some of the functions returning a Task return them "hot" (meaning, already executing their work). If you do not wish to "pause the Main flow", just do not await the Task returned until the end of your workflow. By the way, this should be the case when using Task.Run.

Sometimes, Task are "cold", and started automatically when await is called. But you can start them manually without awaiting them by using Task.Start.

Of course, using Tasks have it's pitfalls and you should should still be aware of what it does behind the scenes. You can still do "bad" thread programming things, for instance cause deadlocks in some situations, or fail to handle exceptions.

Further reading, picked up among many :

but there are many more.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your answer. It seems like the simple solution and I don't know what I was doing so differently that cause the program to sit and wait for the task to finish rather than just run it as a separate thread as it is doing now, nor why it was so difficult to find this answer that I needed to ask here. I still have more research to do so I can figure out how to properly deal with parameters and Task control, but this gets me on the right foot. Exiting the program now works which was the biggest issue with the use of Thread. I'll look at the link you provided as well, thank again.
Yes, using Tasks has its learning curve, hope this will take you one the right track. If you have further question feel free to post another question on Stack Overflow (of course by doing research first), along with some minimal reproducible example, that always helps questions being more focused (and better received by the community)
I mean that's the thing, I didn't just come here as soon as I was stumped, I wrote a basic console app to test various ways of running tasks to see if they could be used this way. I looked them up and every time I'd end up at some ASP .Net deal from Microsoft talking about using async and await for webapis. Even doing base tests where I'd just start the task didn't seem to work until this time. Anyway I'll try to remember to be more brief next time, just wasn't sure if I was missing something in .Net Core for microservices that I should be using (searching brings up webapi stuff).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.