❔ Windows BackgroundService
Hello. So I'm a beginner at C# and a beginner and making services, so I'm not sure how stupid some one the questions I'm about to ask might sound. Regardless I would really appreciate if someone could either explain me things or link to useful documentation.
I have the following questions regarding Windows Services in C#:
1- From my understanding, the flow of the Service goes as follows (I'll be referring to
BackgroundServices
, since that is what the documentation advice me to use, apparently it's the modern approach to making a Service in Windows):
In the Program.cs
file, we have a builder
, we give the builder
information about the classes that are going to do tasks (?) and then we tell it to .Run()
. So I assume this is the code that will run when in the shell I do sc.exe create <service_name.exe>
. Please correct me If I'm wrong. Then I need to start the service so that it starts doing the thing I tell it to do, and I would stop it if I wanted to stop the service. To kill the service I would need to delete it. This would all be done using the sc.exe
.
2- Still regarding Program.cs
, what is a HostApplicationBuilder
, and why do I need one? The documentation that I followed (https://learn.microsoft.com/en-us/dotnet/core/extensions/windows-service) used a bunch of Host
stuff in the Program.cs
file but didn't really explained what was going on, so this is my biggest question mark so far, is what is going on with the Program.cs
file.106 Replies
This is the code in the file, for reference. I have more questions but I think maybe if I understand the base I might figure out the rest. Main questions I have regarding that code:
What is the structure of a Service? What files does it need to have, what files should do what things, is the code in
Program.cs
always like that? Who calls that code, can I rename the file Program.cs
, or is it like a file it needs to have? What is each instruction in the Program.cs
doing, and is it standard to do what they did in the guide?Do you know what dependency injection is?
the core idea here is that all the code in
Program.cs
is just setting up your service. Its not actually your service itself, its just "glue" code to configure things.
HostApplicationBuilder
and the Host
class are from Microsoft.Extension.Hosting
, a namespace that contains what is often called "the .NET generic host"
turns out its fairly common to need configuration files, logging and some background workers, so the generic host was made to support this "workflow"
DI (dependency injection) is an important component here, as thats what manages most of your objects and their lifetimes during the execution of the program.
builder.Services
is a IServiceCollection
, which is the object that is used to configure your DI setup (before being built)
the last 2 rows just build the builder into a host, kind of like baking a cake once the dough is mixed, and then it finally runs the host, which will run your IHostedService
, in this case... WindowsBackgroundService
I don not know what dependency injection is.
Then I suggest you try to find out. It will be important.
I will, thank you for mentioning that.
So there is one thing I didn't understand. You mentioned that " its fairly common to need configuration files, logging and some background workers". Does this mean that I am making a Service that contains BackgroundWorkers?
See, the main issue here is that I lack understanding that I didn't get from just reading the documentation I linked.
yes, your entire service is in theory a background worker
So the
JokeService
and WindowsBackgroundService
are what exactly?
They are both combined into a single service when I build?JokeService
is ... something. Its registered as a singleton, so there can only be one of them
WindowsBackgroundService
is a class that implements IHostedService
(or BackgroundWorker
)So, with the
builder.Services.Addxxx
syntax, what am I doing exactly?adding things to your DI service provider
basically telling the DI what things will be available and what lifetimes they have
I might be getting off by the class names.
JokeService
and WindowsBackgroundService
aren't actually Services, or are they?WindowsBackgroundService
is.
JokeService
can be, but there are no restrictions on it (since its being added by the generic AddSingleton
method, that has no requirements)
its likely just a "logic class"So in the end, I would have listed in the Service Control Manager a single Service named ".NET Joke Service". And that service would have a service running within itself of type
WindowsBackgroundService
?
(or more, if I added them to the buid.Services
)
(In this case, JokeService
is just a logic class like you mentioned)Your entire program will be the "service" listed in the service control manager
So the Service name is just a node to N services?
?
Let's say I have 3 more classes similar to
WindowsBackgroundService
.
Let's also say that, in the Program.cs
, I do builder.Services.AddHostedService
to each of them.
When I start my Service, what would happen, would the Service have 4 total intances, one for each type, or would the Service just be a Node to 4 independent Services, one for each type?
This is what I'm not understanding.not sure what you mean by "Node" here
its not a relevant term
A folder
something that groups things
the name of a set
okay, thats not what Node means, but yeah
It could mean that
your "service", which is actually your program, would run all 4 hosted services simultaneously
And these 4 hosted services would be independent of each other?
yes and/or no 🙂
they can be, they can also not be
So they are related entities
perhaps they send messages to eachother when "things" happen
or they dont
they CAN be.
but they each got started individually
and they all have access to the same services (via the DI service provider)
so its not at all unreasonable to think that they might use one of those services to communicate
I was assigned a task to separete a big service into smaller ones. This is so that I can then learn how to use Kubernetes to orquestrat them, after I pujt them in containers.
If I understand things correctly, in the
Program.cs
file, doing builder.Services.AddHostedService
for each of them (assuming I have a type of each of them), would not do it, I would need separate projects for each, correct?If you are going to use kubernetes, then they need to be separate executables yes
k8 isnt aware of the concept of windows services. it runs programs.
the term "service" is incredibly overloaded and means different things in different contexts, just so we got that clear 🙂
it means one thing in C#, one in windows, one in linux, one in kubernetes etc
Okay things are starting to make more sense. Thank you so far for the patience you are having, I can be slow when I don't understand concepts at first.
Yes I agree that Service has too many different meanings, maybe that is part of why I'm having a bit of trouble at first.
I have another question.
Services don't really have a Main function, they just provide functionalities, kinda like a library. This is correct, yes?
They don't have a
Main
function as such (since thats an application entrypoint), but they do have something... similarYou are referring to the
ExecuteAsync
function, correct?sure, or
StartAsync/StopAsync
depends on what base you useNotice the following code that I used from the guide I previously linked:
The main question I have is this, I never really interacted with Services before, let alone developed one.
How would I interact with this service if I wanted to?
The service works autonomously as is, but let's say I wanted to pass it something and wait for a output, how would I do that in a Service?
you wouldn't
services are by nature entirely self-contained
they dont take input as such
if you need that, you'll be wanting to base your service on something that allows input, such as an HTTP service (ASP.NET), or a TCP listener
Don't they work be requests? My task is to make a service that a Delphi program would pass in a JSON file, the service would do some parsing, convert that to a HTTP request, send the resquest to a server elsewere, and parse the responce back to JSON and to the Delphi application
how would the delphi program "pass the json"?
by what protocol?
Sorry, I might have not typed things in the correct way
It passes by parameter
?
how?
Things cant just magically talk to other things
my webbrowser uses HTTP to talk to web servers
a game might use UDP to send packets to the game server
I will ask it to the previous maintainer of the project, I'll reply shortly.
you need to establish a connection between two things for them to talk. Thats done over some form of protocol. On linux, the simplest way would be either file streams, or pipes
today, its very common to use HTTP, even if you dont serve webpages
its just convenient to spin up a simple webserver that has an API you can talk to
Okay so, there is a RestAPI
Delphi communicates to the API via URL
right, so your service is actually a webservice
meaning you should NOT be basing it on the above code, but rather on ASP.NET
something like https://service-url.com?parm=1&parm=2 etc
I see, so different kind of project entirely?
yep
its gonna be fairly similar thou
but it uses a different boilerplate
you'll still use a builder and a host
and
builder.services.add...
I see, so I assume this is why I would use something called IIS?
no
dear god no
Not sure what that is yet tho, it's something they told me I would use
asp.net comes with a very good webserver called "Kestrel"
you do NOT need to use IIS
in fact, I highly recommend you don't
Does it need a licence?
nope
Okay, so for the rest of the day I will read documentation regarding ASP.NET Services? Is that the correct name for me to look for?
Microsoft
ASP.NET Web APIs | Rest APIs with .NET and C#
Build secure REST APIs with C# that reach a broad range of clients, including browsers and mobile devices. Build and deploy on Linux, macOS, and Windows.
this is what you want.
Thank you a bunch.
I would need to set up a VM to test the service, correct? Does the link you posted regard that?
no?
you dont need a VM
it runs just fine on your local machine
when you are happy with it, you'd make a container using docker or something similar
kubernetes runs containers
I was told I would need a VM for this, but no one has really worked with this here, it's kind of a new thing we are trying to use and the project was assigned to me.
Anyways, your help has been very helpful. I really appreciate it.
I'll surely come here again with more question in the near future.
Thanks.
you'll not need a local VM, but you really do need to read up on a lot of things..
ASP.NET web apis
Docker
Kubernetes
networking (basics)
this should take you a few weeks/months to learn 🙂
Yes, the kubernets will be a big thing, I have a lot of reading and studying to do...
yep.
I guess this is the part of my career that I get good ahahaha
my number one tip there is to download and learn "k9s"
its a kubernetes tool that makes life soooooo much better
I use it all the time
https://k9scli.io/
Thank you for mentioning that, I was not aware of that tool, I'll definitly chek it out after I get the services running
you can visually move around in the cluster, inspecting nodes, pods, namespaces, even edit things (but I recommend using something like helm for this)
Noted
Is it fine to reuse this thread to continue with the questions when I have them?
Or would It make more sense to make a new thread for each question?
sure, if its still open
the bot will ask if its still relevant after 24 hours of inactivity
threads are not usually meant for really long ongoing things as such
I see
I'll get to the ASP.NET documentation and try to get something working. I have a better understanding regarding Services after your explanation now
Thank you. :)
1º - https://learn.microsoft.com/en-us/aspnet/core/web-api/?WT.mc_id=dotnet-35129-website&view=aspnetcore-7.0
2º - https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-7.0&tabs=visual-studio
The documentation you linked refers to the first link and that link refers to the second link if my goal is to create a minimal web API.
I think I want the second link, correct? Since the goal is to make a bunch of Web Services, and from reading a bit, it seems more suited to put in a container since they would have minimal dependencies.
thats not what "minimal" in minimal api refers to
its a design decision, controllers vs minimal api
they do the same thing, they just look different
but if your API is very simple, with a low number of endpoints, minimal API is a good fit
The original Service basically handles a bunch of requests to different places, and the main goal is to split that, to make a service for each kind of place
I think it's a minimal thing from my understanding
What does that mean? Will your delphi application contact multiple internal services?
that doesnt seem like a good idea.
I'd want my client application to have a single endpoint it talks to, and have that service be responsible for any further subdivision if needed
(but if all you do is turn a json payload into a web request and returns it, why even bother splitting it)
This is a finance related requests
The issue we were having is that
some kinds of requests are more commum then others
and we are talking about a huge number or requests
Sure
so in orther to scale things
we want to split into services
so that its possible to scale the things that need scaling
and not the whole thing
plus we would get deployment advantages
doing work on a particular service woulnt need to deploy the whole thing
etc
so, that makes sense, if the work is actually being done on your end
but you said all it does is forward a request
thats not very load intensive, even for a ton of requests
if you actually do some "real work" as part of the request, then yes, splitting might make sense
it's a bit intensive yes, because we have a very big number of clients, and because the places we talk to do not keep track of sesison, so talking to them needs a bunch of requests to happen
this is because in my country its a pain to deal with the apis of the finance and legal stuff, it forces us to have to work around that
its gets a bit load intensive
hm okay. it will be a bit messy for your delphi client to coordinate, but it can work
kubernetes can handle scaling and load balancing for you, but the requests must still be directed to the correct place. You might want to consider an API gateway
that can act as a single point of entry, so your delphi client can still have the nice "single connection" thing
kinda like a router?
but its actually talking to the gateway that redirects all the requests to their dedicated clusters
yeah, thats what an API gateway is
How would that affect my design? so the entry point is the API gateway, its job is I assume to figure out what kind of request is, and forward it to the ASP.NET Service that handles that type of request?
and also the API gateway would also need to reply to the client.
Something like this?
so for example, your gateway might get requests that look like...
each of those three routes (finance, bank, currency) would in this example get routed to their own load balancer
the balancer will send it to an available node
and if there are none, it would ask kubernetes to start a new node
auto-scaling
(the nodes here are actually
Pod
s in kubernetes lingo)So that design is taking into account that it will be managed by some orquestrator, in this case k8s, correct?
yes, all of the boxes except the client would be inside the k8 cluster
When making something in this scale, I was not aware that I would take into account the Kubernets
Would this be transparent code-wise?
?
Let me draw What I think would be happening
not sure exactly what you mean by that
https://excalidraw.com/ if you need a good fast drawing tool 🙂
entirely webbased too
Thanks I was using paint :p
Iill try taht
I apologise in advance for my horrible mouse letter
This is from the project point of view
yep
I would have a Project for the API Gateway, and a project for each of the service, correct?
Kuberenets desgin would be like the image you shared
well, there are ready made api gateways and load balancers you could use
not having to make your own
the only thing you'd code on your own was the services
Hm, I would have to ask If I can do that, since I'm not 100% sure they want to rely on something that would not be maintained by us to use
Wouldn't recommend writing your own - its not as easy as it sounds.
That was going to be my next question, i see
What options out there do I have?
making one is easy.
making a good one is very hard.
Interesting
I'm no expert, but I've heard good things about "KrakenD"
This is going to be a challenge for me, It's the first time I'm actually using all this new technology
The website seems nice, I'll definitly consider using it
The services would still be ASP.NET services correct, even if I don't talk with them directly from the Delphi client?
yep, they are still normal http services
Okay, I think I have enough information to start reading and trying things out.
Would you recommend me starting form something in particular? I was thinking about starting with the ASP.NET Services first, then see if they behave correctly, then set up the API Gateway, check that, and then move to Docker and Kubernets.
This seems like a good approach, small steps at a time, but I could be wrong
yeah that seems fine
Alright, thank you again for walking me thru all this, I'd probably still be making BackgroundServices by this time and thinking I was making progress ahahaha
So I finished the following tutorial: https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-7.0&tabs=visual-studio
I tested things out and everything seems Okay, I understood the concept which is nice.
I do have some questions.
First of all, that code is all in the
Program.cs
file. Is there a way to move the functions to another file, so that it's cleaner?
If I just create a file and make a namespace TodoApi, and start writing the function definitions, will It recognize them?
Also, there is something I'm a bit worried about
The previous service had a helper thing inside it, and that helper thing is basically a Parser
The need for this Parser is the following, the servers that I will communicate they dont reply in JSON
they reply the actual web page
so I need to Parse the response, cut down everything I don't need, so that I can work with the data
This Parser should be common to all the services I make from the bigger one
What alternatives to I have in this situation?Absolutely, just make a static class with a static method and you can map that, or look into something like https://fast-endpoints.com/
FastEndpoints
FastEndpoints
FastEndpoints is a developer friendly alternative to Minimal APIs & MVC for rapid REST API development.
make a class library that all the other services can then import
if your reply is in HTML, the term you're looking for is actually a web scraper - I suggest using something like AngleSharp to find the information you need
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.