So I was stuck on this problem for about a week. I was trying to run a project to recieve a TCP connection and start a SignalR Hub as a Service. Both worked perfectly running the project as a .exe file. The TCP part would work perfectly, however I was having problems with the SignalR side.
The reason ended up being the using statement.
Before
using (WebApp.Start<SignalrStartup>(url))
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Server running on {0}", url); // was url
Console.WriteLine("ID\tMessage");
Console.ReadLine();
}
After
WebApp.Start<SignalrStartup>(url);
I had tried running the the code with the Console.WriteLine()
commented out, as I thought it might be throwing an exception as the is no console to output to once run as a service. This also didn't work, but also wouldn't work as a .exe file either as it needed the Console.ReadLine()
to keep the console open, sort of how you need it to keep HelloWorld.cs open. Once the using wrapper was removed along with the console, it would then work in both the .exe and the service.
I have read that the using statement kills objects in it once you leave the wrapper. But I don't understand how the After bit of code keeps the .exe code open once running. Is there any point in using using or have I been using it wrong?
Edit
protected override void OnStart(string[] args)
{
Task.Factory
.StartNew(() => StartTCP())
.ContinueWith(t => StartSignalR());
}
The call is being made from the StartSignalR()
method.
Stay calm, rational and polite. Give reasons for terminating the relationship, but keep emotion and name-calling out of the conversation. Follow-up with a phone call. You can start the process with an email, but you should follow-up with a phone call to talk your client through the process and answer any questions.
The problem you're having is that your Console.ReadLine
does a blocking wait for standard input. That will block forever on a windows service and cause the service control manager to time out the service start after 30 seconds. This question has more information about what's going on.
If you remove the entire contents of the using statement, and the statement itself as you have done the server that was started by WebApp.Start
will continue on in the background after your service Start
method completes. This is the correct behaviour of a service.
What you're effectively doing here is to leak the asynchronous workers that WebApp.Start
created. This means that they're still running after the service start completes to listen for requests.
You should probably keep track of the IDisposable
that WebApp.Start
returns though, and dispose it in the Stop
method.
using
?A using
statement makes sure a resource is always disposed when control leaves the using
statement's block. This can be either due to an exception being thrown or because the block completes successfully and control moves on to the next part of the program.
using
statements are used when you know that nothing wants to access the resource after the block has completed. This is usually the case when you're dealing with methods that return an IDisposable
to you. In your case however you don't want to call dispose because you want the threads that WebApp.Start
created to continue after the service has started.
Webapp.Start<> starts worker threads. These threads keeps your exe running, even after the code in your HelloWorld.cs has finished executing. Your exe will not shut down until all worker threads have been stopped.
When you add your "using"-statement, the framework will call Dispose on your SignalR application. This call will stop all the work threads, and your exe will terminate.
The Readline() statement stops the app from reaching the end of the using statement. This means the dispose method is not called until you press enter.
So, for an exe you normally want to use ReadLine the way you do. For a service you want to store a reference to your IDisposable, and call dispose on it in you Stop() method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With