V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Acoffice
V2EX  ›  程序员

dotnet c#应用 docker 终端手动执行正常,打包后异常退出.

  •  
  •   Acoffice · 2022-04-25 12:07:06 +08:00 · 351 次点击
    这是一个创建于 748 天前的主题,其中的信息可能已经有所发展或是发生改变。

    运行环境:

    1. docker
    2. 基础镜像: mcr.microsoft.com/dotnet/runtime:2.1

    相关报错

    Unhandled Exception: System.OperationCanceledException: The operation was canceled.
       at System.Threading.CancellationToken.ThrowOperationCanceledException()
       at System.Threading.ManualResetEventSlim.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
       at System.Threading.Tasks.Task.SpinThenBlockingWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
       at System.Threading.Tasks.Task.InternalWaitCore(Int32 millisecondsTimeout, CancellationToken cancellationToken)
       at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
       at System.Threading.Tasks.Task.Wait(CancellationToken cancellationToken)
       at SY.Hotbit.Service.Program.<>c__DisplayClass8_0.<Subscription>b__1(Object s, EventArgs e)
    

    问题现象

    dotnet publish 打包后,在 Linux 终端手动运行正常,在 dockerfile 注释 cmd 入口点,手动进入 docker 终端运行,也正常.

    但是通过 docker 入口点启动后,就会有上述报错并退出,docker 给出得 exitcode 是 134 和 139.已尝试搜索 StackOverflow 和微软论坛,未找到相关案例.

    然后也没有其它报错信息,无从查起!!!

    特来求助,希望有大神解惑,谢谢!

    第 1 条附言  ·  2022-04-25 14:10:49 +08:00

    结帖!!!

    原因是:.net core控制檯應用程式中,有時候需要使用Console.ReadKey()阻塞,保持視窗活動。像Read(),ReadLine()也可以實現類似需要。這三種方式我在windows、Linux中都沒有問題,正常使用。但是某次我將帶有ReadKey()阻塞程序的程式放到Docker中使用時,發現報錯:“System.InvalidOperationException: Cannot read keys when either application does not have a console or when console input has been redirected. Try Console.Read.at System.ConsolePal.ReadKey(Boolean intercept)”。ReadKey()用不了。讓嘗試使用Read(),跟著提示用了Read(),發現錯是沒報了。但是程式看著想是起不來。原因是Read(),和ReadLine()在Docker中無法起到阻塞程序的作用。


    二、解決辦法:
    
      有問題的程式碼:
    
      
    
    static void Main(string[] args)
    {
        //你的業務邏輯程式碼
        Console.ReadKey();  
    }
      處理辦法:
    
      
    
    private static readonly AutoResetEvent _closingEvent = new AutoResetEvent(false);
    static void Main(string[] args)
    {
        //你的業務邏輯程式碼
        Console.CancelKeyPress += ((s, a) =>
                {
                    Console.WriteLine("程式已退出!");
                    _closingEvent.Set();
                });
        _closingEvent.WaitOne();
    }
      這樣處理後,問題就解決了。退出程式Ctrl+C。
    
    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   974 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 22:27 · PVG 06:27 · LAX 15:27 · JFK 18:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.