简体   繁体   中英

.Net Core console app on Linux will not run as service

I have a continuously running .Net Core (2.1) console app that schedules a number of repeating background tasks using the Quartz.Net scheduler. I am attempting to run the app on a Linux server (16.04). The app runs fine when running as a standalone application. However, when I try to run the app as a systemd service it hangs. The app loads and schedules the various tasks in Quartz.Net, but the scheduled background tasks never execute. What is different about the execution of a service versus standalone?

The systemd service config file is as follows:

[Unit]
Description=FiddleMon.Background


[Service]
User=ubuntu
Restart=on-failure
ExecStart=/home/ubuntu/scripts/start-fiddlemon.background.sh

[Install]
WantedBy=multi-user.target

I don't know if this has anything to do with the situation, but I did notice a difference in the STAT column from the ps aux listing for the app depending on whether it is running standalone or as a service (SLl vs SLl+):

standalone => 1782  1.4  8.4 2923228 171996 pts/1  SLl+ 00:18   0:33 /usr/bin/dotnet FiddleMon.Background.dll

service => 1518  8.9  4.7 2767936 97132 ?       SLl  23:59   0:03 /usr/bin/dotnet FiddleMon.Background.dll  

Any suggestions would be appreciated.

I finally figured out was was going on. The original structure of the Main method in Program.cs was as follows below. This code worked fine when running on Windows and on Linux as a standalone process that was associated with a terminal session. On Linux as soon as the terminal session was terminated the background program would terminate as the main program thread would be terminated as well.

When the program was run as a Linux service there was no terminal session associated with the program so Console.ReadLine() would not cause the thread to block and the program would immediately terminate. The solution was to replace Console.ReadLine() with some code that would cause the thread to block and stay alive so that the background threads managed by Quartz.Net could execute. There are a lot of different ways that this can be accomplished and there are numerous StackOverflow discussions regarding the "best" way to do this. My simple solution was to replace Console.ReadLine with Thread.Sleep(Timeout.Infinite) . This causes the main thread to block and stay alive forever. Note that with this solution if you want to be able to manually terminate the program there needs to be a way to do it outside of the main thread as it is asleep forever.

**Original Code**

    static void Main(string[] args)
    {
        _scheduler = InitializeQuartzScheduler();
        _scheduler.ScheduleBackgroundJob<BackgroundJob1>(Yesterday.At(1, 30).AsPstToUtc(), 1.Hours());
        _scheduler.ScheduleBackgroundJob<BackgroundJob2>(Yesterday.At(0, 10, 30).AsPstToUtc(), 10.Minutes());
        ...
        _scheduler.ScheduleBackgroundJob<BackgroundJob7>(Yesterday.At(1, 45).AsPstToUtc(), 8.Hours());
        _scheduler.ScheduleBackgroundJob<BackgroundJob8>(Yesterday.At(0, 10).AsPstToUtc(), 6.Hours());

        Console.Readline();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM