dasMulli/dotnet-win32-service

Error 109: The pipe has been ended while trying to stop service

jakoss opened this issue · 13 comments

I'm facing a little problem with ending my service. I have an aplication with main loop that is controlled by CancellationTokenSource. This loop is in task that i use to wait.

It looks like that (code is much bigger, so i'll try to focus on issue):

Service is starting like that:

public Task Run()
        {
            var token = cancellationTokenSource.Token;
            logger.LogInformation("Running dispacher");
            return Task.Run(async () => // don't run it on main thread
            {
                while (true)
                {
                    try
                    {
                        token.ThrowIfCancellationRequested();

                        await Task.Delay(TimeSpan.FromMilliseconds(100), token).ConfigureAwait(false); // application logic simulation
                    }
                    catch (TaskCanceledException)
                    {
                        break;
                    }
                    catch (Exception e)
                    {
                        logger.LogError(e, "Exception in dispatcher loop");
                    }
                }
                logger.LogInformation("Dispacher shut down");
            }, token);
        }

Then i keep the reference to this task as mainTask and in Stop method i'm doing something like this:

var cts = Container.GetService<CancellationTokenSource>();
cts.Cancel();
mainTask.Wait();

The problem is application is crashing with error Error 109: The pipe has been ended when i try to stop it as a service. When i'm testing it in console application it is working just fine.

A little debugging showed that crash if happening on line cts.Cancel(); and i'm really stuck in here. There is no exception that i can catch, application just.. crashes.

Have you and idea what am i doing wrong?

Do you have a complete example to test out? it's really hard to tell what could be going on here..

e.g. timeouts, an exception bubbling up the Stop() method etc. all could cause similar issues

I stripped down all logic of my application and left only the "loop" part. Problem still occurs. Here is solution to test: https://drive.google.com/open?id=1U0BH7tBU90PDUrTdh7SV1Krq3W9j7PsH

I do dotnet publish -c Release -r win-x64 and then in publish folder i do PrinterCoreService.exe --register-service. Service is starting and working fine. But when i stop it (in services.msc) it crashes

Have you any luck testing this?

sry for the delay, been travelling and just got back, will take a look later today.

@NekroMancer I find myself unable to reproduce this on my win10 VM, the self-contained published executable seems to work fine..

Could you try to add some minimal exception recording to your app like this?:

        public void Start(string[] startupArguments, ServiceStoppedCallback serviceStoppedCallback)
        {
            try
            {}
            catch (Exception ex)
            {
                File.WriteAllText(@"C:\Temp\startup-err.log", $"{ex.Message}\n{ex.StackTrace}");
                throw;
            }
        }

        public void Stop()
        {
            try
            {}
            catch (Exception ex)
            {
                File.WriteAllText(@"C:\Temp\shutdown-err.log", $"{ex.Message}\n{ex.StackTrace}");
                throw;
            }
        }

and check if those files are created and contain an exception

Well, that's the problem. I tried it and nothing gets logged. The code seems to be killed in the middle of the stop function and nothing gets thrown. I used tracing to check where it's happening and.. it seems to be random.. I mean, something seems to kill process after random time

there is a task.run() in there that calls the stopped callback. could you try removing that? it may have problems when not being called from the correct thread. if that's the problem I may need to change the way it is handled

I removed whole task.run and unfortunetely nothing gets changed. I also checked the event log, nothing there either

Tried it out on another machine - same thing happens

I did more tests and it seems like this is happing only on Windows 10. It doesn't happen on windows server 2012 R2 and 2016

can you check which release of win10? also, try setting

<RuntimeFrameworkVersion>2.0.6</RuntimeFrameworkVersion>

in the csproj (inside a property group) to get the latest runtime version for self-contained applications. I've heard (though only for arm) that there has been some issue where NLog caused uncaught exceptions due to a bug. could you also try to register a handler for AppDomain.UnhandledException to log any unhandled exceptions?

Setting RuntimeFrameworkVersion worked, now it's working like a charm! Thanks :)

I'm not sure why .NET Core isn't setting latest version of the runtime by default when i'm using latest SDK tools. And i'm baffled why they are not warning about this anywhere in documentation..