μΉ΄ν…Œκ³ λ¦¬ 보관물: C#

C#

.NET μ½˜μ†” μ•±μ—μ„œ ν‚€ λˆ„λ¦„μ„ λ“£μŠ΅λ‹ˆλ‹€. ν•΄μ•Όν•©λ‹ˆκΉŒ? while 루프λ₯Ό 감싸고 μžˆλ‹€κ³ 

ν‚€λ₯Ό λˆ„λ₯Ό λ•ŒκΉŒμ§€ (예 Esc: 눌릴 λ•ŒκΉŒμ§€) μ½˜μ†” μ‘μš© ν”„λ‘œκ·Έλž¨μ„ 계속 μ‹€ν–‰ν•˜λ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Όν•©λ‹ˆκΉŒ?

while 루프λ₯Ό 감싸고 μžˆλ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€. ReadKeyν‚€ λˆ„λ₯΄κΈ°λ₯Ό 계속 λ“£κ³  λ“£λŠ” 것이 μ•„λ‹ˆλΌ μž‘λ™μ„ μ°¨λ‹¨ν•˜κ³  ν‚€λ₯Ό μš”κ΅¬ν•˜λŠ” 것이 λ§ˆμŒμ— λ“€μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ .

μ–΄λ–»κ²Œ ν•  수 μžˆμŠ΅λ‹ˆκΉŒ?



λ‹΅λ³€

μ°¨λ‹¨λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것을 μ•Œκ³ μžˆμ„ Console.KeyAvailableλ•Œλ§Œ μ „ν™” ReadKeyν•  수 μžˆλ„λ‘ μ‚¬μš©ν•˜μ‹­μ‹œμ˜€ .

Console.WriteLine("Press ESC to stop");
do {
    while (! Console.KeyAvailable) {
        // Do something
   }
} while (Console.ReadKey(true).Key != ConsoleKey.Escape);

λ‹΅λ³€

μ ‘κ·Ό 방식을 μ•½κ°„ λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆλ‹€- Console.ReadKey()앱을 쀑지 ν•˜λŠ” 데 μ‚¬μš© ν•˜μ§€λ§Œ λ°±κ·ΈλΌμš΄λ“œ μŠ€λ ˆλ“œμ—μ„œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜μ‹­μ‹œμ˜€.

static void Main(string[] args)
{
    var myWorker = new MyWorker();
    myWorker.DoStuff();
    Console.WriteLine("Press any key to stop...");
    Console.ReadKey();
}

μ—μ„œ myWorker.DoStuff()κΈ°λŠ₯은 λ‹€μŒ λ°°κ²½ μŠ€λ ˆλ“œμ—μ„œ λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 것 (μ‚¬μš©μ„ Action<>()λ˜λŠ” Func<>()그것을 ν•  μˆ˜μžˆλŠ” μ‰¬μš΄ 방법이닀), μ¦‰μ‹œ λ°˜ν™˜ν•œλ‹€.


λ‹΅λ³€

κ°€μž₯ 짧은 방법 :

Console.WriteLine("Press ESC to stop");

while (!(Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape))
{
    // do something
}

Console.ReadKey()차단 κΈ°λŠ₯이며 ν”„λ‘œκ·Έλž¨ 싀행을 μ€‘μ§€ν•˜κ³  ν‚€ λˆ„λ¦„μ„ κΈ°λ‹€λ¦½λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ Console.KeyAvailableλ¨Όμ € 확인 덕뢄에 while루프가 μ°¨λ‹¨λ˜μ§€ μ•Šκ³  Escλ₯Ό λˆ„λ₯Ό λ•ŒκΉŒμ§€ μ‹€ν–‰ λ©λ‹ˆλ‹€.


λ‹΅λ³€

Jason Curs ( http://www.pluralsight.com)의 C #μ—μ„œ .NET μ½˜μ†” μ‘μš© ν”„λ‘œκ·Έλž¨ ꡬ좕 λΉ„λ””μ˜€ μ €μ£Ό

μ—¬λŸ¬ 개의 싀행쀑인 ν”„λ‘œμ„ΈμŠ€λ₯Ό κ°–κΈ° μœ„ν•΄ λ‹€μŒμ„ μˆ˜ν–‰ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  static void Main(string[] args)
    {
        Console.CancelKeyPress += (sender, e) =>
        {

            Console.WriteLine("Exiting...");
            Environment.Exit(0);
        };

        Console.WriteLine("Press ESC to Exit");

        var taskKeys = new Task(ReadKeys);
        var taskProcessFiles = new Task(ProcessFiles);

        taskKeys.Start();
        taskProcessFiles.Start();

        var tasks = new[] { taskKeys };
        Task.WaitAll(tasks);
    }

    private static void ProcessFiles()
    {
        var files = Enumerable.Range(1, 100).Select(n => "File" + n + ".txt");

        var taskBusy = new Task(BusyIndicator);
        taskBusy.Start();

        foreach (var file in files)
        {
            Thread.Sleep(1000);
            Console.WriteLine("Procesing file {0}", file);
        }
    }

    private static void BusyIndicator()
    {
        var busy = new ConsoleBusyIndicator();
        busy.UpdateProgress();
    }

    private static void ReadKeys()
    {
        ConsoleKeyInfo key = new ConsoleKeyInfo();

        while (!Console.KeyAvailable && key.Key != ConsoleKey.Escape)
        {

            key = Console.ReadKey(true);

            switch (key.Key)
            {
                case ConsoleKey.UpArrow:
                    Console.WriteLine("UpArrow was pressed");
                    break;
                case ConsoleKey.DownArrow:
                    Console.WriteLine("DownArrow was pressed");
                    break;

                case ConsoleKey.RightArrow:
                    Console.WriteLine("RightArrow was pressed");
                    break;

                case ConsoleKey.LeftArrow:
                    Console.WriteLine("LeftArrow was pressed");
                    break;

                case ConsoleKey.Escape:
                    break;

                default:
                    if (Console.CapsLock && Console.NumberLock)
                    {
                        Console.WriteLine(key.KeyChar);
                    }
                    break;
            }
        }
    }
}

internal class ConsoleBusyIndicator
{
    int _currentBusySymbol;

    public char[] BusySymbols { get; set; }

    public ConsoleBusyIndicator()
    {
        BusySymbols = new[] { '|', '/', '-', '\\' };
    }
    public void UpdateProgress()
    {
        while (true)
        {
            Thread.Sleep(100);
            var originalX = Console.CursorLeft;
            var originalY = Console.CursorTop;

            Console.Write(BusySymbols[_currentBusySymbol]);

            _currentBusySymbol++;

            if (_currentBusySymbol == BusySymbols.Length)
            {
                _currentBusySymbol = 0;
            }

            Console.SetCursorPosition(originalX, originalY);
        }
    }

λ‹΅λ³€

λ‹€μŒμ€ λ‹€λ₯Έ μŠ€λ ˆλ“œμ—μ„œ 무언가λ₯Ό μˆ˜ν–‰ν•˜κ³  λ‹€λ₯Έ μŠ€λ ˆλ“œμ—μ„œ λˆ„λ₯Έ ν‚€μ˜ μ²­μ·¨λ₯Ό μ‹œμž‘ν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€. μ‹€μ œ ν”„λ‘œμ„ΈμŠ€κ°€ μ’…λ£Œλ˜κ±°λ‚˜ μ‚¬μš©μžκ°€ Escν‚€ λ₯Ό 눌러 ν”„λ‘œμ„ΈμŠ€λ₯Ό μ’…λ£Œν•˜λ©΄ μ½˜μ†”μ΄ 처리λ₯Ό μ€‘μ§€ν•©λ‹ˆλ‹€ .

class SplitAnalyser
{
    public static bool stopProcessor = false;
    public static bool Terminate = false;

    static void Main(string[] args)
    {
        Console.ForegroundColor = ConsoleColor.Green;
        Console.WriteLine("Split Analyser starts");
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("Press Esc to quit.....");
        Thread MainThread = new Thread(new ThreadStart(startProcess));
        Thread ConsoleKeyListener = new Thread(new ThreadStart(ListerKeyBoardEvent));
        MainThread.Name = "Processor";
        ConsoleKeyListener.Name = "KeyListener";
        MainThread.Start();
        ConsoleKeyListener.Start();

        while (true)
        {
            if (Terminate)
            {
                Console.WriteLine("Terminating Process...");
                MainThread.Abort();
                ConsoleKeyListener.Abort();
                Thread.Sleep(2000);
                Thread.CurrentThread.Abort();
                return;
            }

            if (stopProcessor)
            {
                Console.WriteLine("Ending Process...");
                MainThread.Abort();
                ConsoleKeyListener.Abort();
                Thread.Sleep(2000);
                Thread.CurrentThread.Abort();
                return;
            }
        }
    }

    public static void ListerKeyBoardEvent()
    {
        do
        {
            if (Console.ReadKey(true).Key == ConsoleKey.Escape)
            {
                Terminate = true;
            }
        } while (true);
    }

    public static void startProcess()
    {
        int i = 0;
        while (true)
        {
            if (!stopProcessor && !Terminate)
            {
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("Processing...." + i++);
                Thread.Sleep(3000);
            }
            if(i==10)
                stopProcessor = true;

        }
    }

}

λ‹΅λ³€

Visual Studioλ₯Ό μ‚¬μš©ν•˜λŠ” 경우 디버그 λ©”λ‰΄μ—μ„œ β€œλ””λ²„κΉ…μ—†μ΄ μ‹œμž‘β€μ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

β€œκ³„μ†ν•˜λ €λ©΄ 아무 ν‚€λ‚˜ λˆ„λ₯΄μ‹­μ‹œμ˜€.”라고 μžλ™μœΌλ‘œ μ“°μ—¬μ§‘λ‹ˆλ‹€. μ‘μš© ν”„λ‘œκ·Έλž¨μ΄ μ™„λ£Œλ˜λ©΄ μ½˜μ†”μ— ν‘œμ‹œλ˜λ©° ν‚€λ₯Ό λˆ„λ₯Ό λ•ŒκΉŒμ§€ μ½˜μ†”μ΄ μ—΄λ¦° μƒνƒœλ‘œ μœ μ§€λ©λ‹ˆλ‹€.


λ‹΅λ³€

λ‹€λ₯Έ λ‹΅λ³€ 쀑 일뢀가 잘 μ²˜λ¦¬λ˜μ§€ μ•ŠλŠ” 경우λ₯Ό ν•΄κ²°ν•©λ‹ˆλ‹€.

  • 응닡 : ν‚€ λˆ„λ₯΄κΈ° 처리 μ½”λ“œμ˜ 직접 μ‹€ν–‰; 폴링 μ§€μ—° λ˜λŠ” μ§€μ—° μ§€μ—° λ°©μ§€
  • 선택 사항 : μ „μ—­ ν‚€ λˆ„λ₯΄κΈ°κ°€ μ„ νƒλ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€ . κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ 앱이 μ •μƒμ μœΌλ‘œ μ’…λ£Œλ˜μ–΄μ•Όν•©λ‹ˆλ‹€
  • 우렀의 뢄리 : 덜 침슡적 인 μ²­μ·¨ μ½”λ“œ; 일반 μ½˜μ†” μ•± μ½”λ“œμ™€ λ…λ¦½μ μœΌλ‘œ μž‘λ™ν•©λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€μ˜ λ§Žμ€ μ†”λ£¨μ…˜μ—μ„œμ— λŒ€ν•œ 폴링 Console.KeyAvailableλ˜λŠ” 차단 이 포함 λ˜μ–΄ Console.ReadKeyμžˆμŠ΅λ‹ˆλ‹€. Consoleμ—¬κΈ° μ—μ„œ .NET 이 맀우 ν˜‘μ‘°μ μ΄μ§€ μ•Šλ‹€λŠ” 것은 μ‚¬μ‹€μ΄μ§€λ§Œ Task.Run,보닀 ν˜„λŒ€μ μΈ Asyncλ“£κΈ° λͺ¨λ“œλ‘œ μ „ν™˜ ν•˜λŠ” 데 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€ .

μ•Œμ•„μ•Ό ν•  μ£Όμš” λ¬Έμ œλŠ” 기본적으둜 μ½˜μ†” μŠ€λ ˆλ“œκ°€ Asyncμž‘λ™ν•˜λ„λ‘ μ„€μ •λ˜μ–΄ μžˆμ§€ μ•Šλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 즉, mainν•¨μˆ˜ 의 ν•˜λ‹¨μ—μ„œ λ–¨μ–΄μ§ˆ λ•Œ Asyncμ™„λ£Œλ₯Ό 기닀리지 μ•Šκ³  AppDoman 및 ν”„λ‘œμ„ΈμŠ€κ°€ μ’…λ£Œλ¨μ„ μ˜λ―Έν•©λ‹ˆλ‹€. . 이λ₯Ό ν•΄κ²°ν•˜λŠ” μ μ ˆν•œ 방법은 Stephen Cleary의 AsyncContext λ₯Ό μ‚¬μš© Asyncν•˜μ—¬ 단일 μŠ€λ ˆλ“œ μ½˜μ†” ν”„λ‘œκ·Έλž¨μ„ μ™„μ „νžˆ μ§€μ›ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ ν‚€ λˆ„λ¦„ λŒ€κΈ°μ™€ 같은 κ°„λ‹¨ν•œ κ²½μš°μ—λŠ” 전체 νŠΈλž¨ν΄λ¦°μ„ μ„€μΉ˜ν•˜λŠ” 것이 과도 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ•„λž˜ μ˜ˆμ œλŠ” μΌμ’…μ˜ 반볡 배치 νŒŒμΌμ— μ‚¬μš©λ˜λŠ” μ½˜μ†” ν”„λ‘œκ·Έλž¨μž…λ‹ˆλ‹€. 이 경우 ν”„λ‘œκ·Έλž¨μ΄ μž‘μ—…μœΌλ‘œ μ™„λ£Œλ˜λ©΄ 일반적으둜 ν‚€λ₯Ό λˆ„λ₯΄μ§€ μ•Šμ•„λ„ μ’…λ£Œ ν•œ λ‹€μŒ 선택적 ν‚€ λˆ„λ₯΄κΈ°λ₯Ό ν—ˆμš© ν•˜μ—¬ 앱이 μ’…λ£Œ λ˜μ§€ μ•Šλ„λ‘ ν•©λ‹ˆλ‹€. 사이클을 μΌμ‹œ μ€‘μ§€ν•˜μ—¬ 사물을 κ²€ν† ν•˜κ±°λ‚˜ μž¬κ°œν•˜κ±°λ‚˜ μΌμ‹œ 쀑지λ₯Ό μ•Œλ €μ§„ β€˜μ œμ–΄μ β€™μœΌλ‘œ μ‚¬μš©ν•˜μ—¬ 배치 νŒŒμΌμ„ μ™„μ „νžˆ 쀑단 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

static void Main(String[] args)
{
    Console.WriteLine("Press any key to prevent exit...");
    var tHold = Task.Run(() => Console.ReadKey(true));

    // ... do your console app activity ...

    if (tHold.IsCompleted)
    {
#if false   // For the 'hold' state, you can simply halt forever...
        Console.WriteLine("Holding.");
        Thread.Sleep(Timeout.Infinite);
#else                            // ...or allow continuing to exit
        while (Console.KeyAvailable)
            Console.ReadKey(true);     // flush/consume any extras
        Console.WriteLine("Holding. Press 'Esc' to exit.");
        while (Console.ReadKey(true).Key != ConsoleKey.Escape)
            ;
#endif
    }
}

이 글은 C# μΉ΄ν…Œκ³ λ¦¬λ‘œ λΆ„λ₯˜λ˜μ—ˆκ³  λ‹˜μ— μ˜ν•΄ 에 μž‘μ„±λμŠ΅λ‹ˆλ‹€.