来自Dotnet Core 2.0 app的Docker Graceful Shutdown

时间:2018-06-01 15:17:28

标签: docker .net-core

我有一个在本地Docker Linux容器(Docker CE 18.03.1稳定通道)中运行的.NET Core 2.0控制台应用程序,我正在尝试处理正常关闭。

我的应用包含AppDomain.CurrentDomain.ProcessExitAssemblyLoadContext.Default.Unloading的处理程序:

        AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
        AssemblyLoadContext.Default.Unloading += Default_Unloading;

处理程序只是在调用时编写日志消息。

我发现,当我执行docker stop <containerid>时,既不会调用处理程序,也会在短暂延迟后调用。容器只是停止运行。我已经尝试在Visual Studio中调试应用程序并尝试在没有调试器的情况下运行。在所有情况下,处理程序都没有被调用。

我还缺少其他一些神奇的咒语吗?

2 个答案:

答案 0 :(得分:4)

我无法重现此行为。

这是我在控制台应用中使用的代码:

    private static readonly AutoResetEvent _closing = new AutoResetEvent(false);

    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
        AssemblyLoadContext.Default.Unloading += Default_Unloading;

        Task.Factory.StartNew(() =>
        {
            while (true)
            {
                Console.WriteLine(DateTime.Now.ToString());
                Thread.Sleep(1000);
            }
        });
        Console.CancelKeyPress += new ConsoleCancelEventHandler(OnExit);
        _closing.WaitOne();
    }

    private static void Default_Unloading(AssemblyLoadContext obj)
    {
        Console.WriteLine("unload");
    }

    private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
    {
        Console.WriteLine("process exit");
    }

    protected static void OnExit(object sender, ConsoleCancelEventArgs args)
    {
        Console.WriteLine("Exit");
        _closing.Set();
    }

使用此docker文件:

FROM microsoft/dotnet:2.0-sdk
WORKDIR /app

# copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# copy and build everything else
COPY . ./
RUN dotnet publish -c Release -o out
ENTRYPOINT ["dotnet", "out/shutdown.dll"]

这是输出:(使用docker stop <id>

06/01/2018 16:31:16
06/01/2018 16:31:17
06/01/2018 16:31:18
unload
process exit

我使用Docker for Windows和Linux容器。

答案 1 :(得分:0)

非常奇怪的行为。
我遇到了同样的问题,对我来说,当我在dockerfile中使用以下入口点时,它不起作用

ENTRYPOINT dotnet DockerTest.dll

当我将其更改为以下内容时,它有效

ENTRYPOINT ["dotnet", "DockerTest.dll"]

我希望这会有所帮助:)