.NET কনসোল অ্যাপ্লিকেশনে কী টিপুন


224

কী প্রেস না হওয়া পর্যন্ত আমি কীভাবে আমার কনসোল অ্যাপ্লিকেশন চালিয়ে যেতে পারি ( Escযেমন টিপছে?)

আমি ধরে নিচ্ছি কিছুক্ষণ লুপের চারপাশে এটি জড়িয়ে আছে। ReadKeyএটি অপারেশনটিকে বাধা দেয় এবং চাবিটি চাওয়ার চেয়ে কেবল চালিয়ে যাওয়া এবং কী প্রেসটি শোনার চেয়ে পছন্দ করি না ।

কিভাবে এই কাজ করা যেতে পারে?

উত্তর:


343

Console.KeyAvailableএমনটি ব্যবহার করুন যাতে আপনি কেবল ReadKeyযখন কল করেন তখনই এটি ব্লক হবে না:

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

6
তবে আপনি যদি রিডলাইন () এর পরিবর্তে এটি করেন তবে আপনি "আপ" কী টিপে ইতিহাস পুনরুদ্ধার করার দুর্দান্ত বৈশিষ্টটি হারাবেন।
v.oddou

3
@ v.oddou শেষ লাইনের পরে, কেবল আপনার যোগ করুন Console.ReadLine()এবং আপনি সেট করেছেন, না?
গাফি

1
এই লুপটি প্রচুর সিপিইউ / র‍্যাম ব্যবহার করবে না? তা না হলে কেমন হয়?
সোফিয়া

78

আপনি আপনার দৃষ্টিভঙ্গিটি সামান্য পরিবর্তন করতে পারেন - 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<>()একটি সহজ উপায় এটা করতে), তারপর অবিলম্বে ফিরে যান।


60

সংক্ষিপ্ততম উপায়:

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

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

Console.ReadKey()এটি একটি ব্লকিং ফাংশন, এটি প্রোগ্রামটির সঞ্চালন বন্ধ করে দেয় এবং একটি মূল প্রেসের জন্য অপেক্ষা করে, তবে Console.KeyAvailableপ্রথমে যাচাই করার জন্য ধন্যবাদ , whileলুপটি অবরুদ্ধ নয়, তবে Escচাপ দেওয়া অবধি চলমান ।


এখন পর্যন্ত সবচেয়ে সহজ উদাহরণ। ধন্যবাদ.
joelc

18

ভিডিও অভিশপ্ত বিল্ডিং থেকে। জেসন রবার্টস দ্বারা সি # তে নেট কনসোল অ্যাপ্লিকেশনগুলি http://www.pluralsight.com এ

আমরা একাধিক চলমান প্রক্রিয়া অনুসরণ করতে নিম্নলিখিত করতে পারে

  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);
        }
    }

2
আমার কনসোল অ্যাপ্লিকেশনটি দিয়ে আপনি যে পদ্ধতিটি করার চেষ্টা করছিলাম সে সম্পর্কে আপনি কি কিছুটা ব্যাখ্যা করতে পারেন the কোডটির ব্যাখ্যাটি দুর্দান্ত।
নায়ফ হার্ব

@ নায়াফারব একগুচ্ছ কাজ সেটআপ করুন, সেগুলি শুরু করুন, এবং ওয়েটএল সমস্ত ফিরে না আসা পর্যন্ত অপেক্ষা করবেন। অতএব স্বতন্ত্র কাজগুলি আর ফিরে আসবে না এবং এটি বাতিল চ্যানেলপ্রেস ট্রিগার না করা অবধি চিরকাল অব্যাহত থাকবে।
wonea

Console.CursorVisible = false;কার্সার ঝলকানো গ্লিটস এড়ানো ভাল হবে। এই লাইনটিকে static void Main(string[] args)ব্লকের প্রথম লাইন হিসাবে যুক্ত করুন ।
হিতেশ

12

আপনার জন্য আলাদা থ্রেডে কিছু করার এবং ভিন্ন থ্রেডে চাপানো কীটি শুনতে শুরু করার জন্য এখানে একটি পদ্ধতির উপায় রয়েছে। এবং যখন আপনার আসল প্রক্রিয়াটি শেষ হবে বা ব্যবহারকারী 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;

        }
    }

}

5

আপনি যদি ভিজ্যুয়াল স্টুডিও ব্যবহার করছেন তবে আপনি ডিবাগ মেনুতে "স্টার্ট উইথ ডিবাগিং" ব্যবহার করতে পারেন।

এটি স্বয়ংক্রিয়ভাবে "চালিয়ে যাওয়ার জন্য যে কোনও কী টিপুন write" লিখবে। অ্যাপ্লিকেশন সমাপ্ত হওয়ার পরে আপনার জন্য কনসোলটিতে এবং কোনও কী চাপানো অবধি আপনার জন্য কনসোলটি খোলা থাকবে।


3

অন্যান্য উত্তরগুলির কিছু ভালভাবে পরিচালনা করে না এমন কেসগুলিতে সম্বোধন করা:

  • প্রতিক্রিয়াশীল : কীপ্রেস হ্যান্ডলিং কোডের সরাসরি সম্পাদন; ভোটদান বা ব্লক বিলম্বের অস্পষ্টতা এড়ানো
  • বিকল্পতা : গ্লোবাল কিপ্রেসটি অপ্ট-ইন ; অন্যথায় অ্যাপটি স্বাভাবিকভাবে প্রস্থান করা উচিত
  • উদ্বেগ পৃথককরণ: কম আক্রমণাত্মক শ্রবণ কোড; সাধারণ কনসোল অ্যাপ কোডটি স্বাধীনভাবে পরিচালনা করে।

এই পৃষ্ঠার অনেকগুলি সমাধানে পোলিং Console.KeyAvailableবা ব্লক করা জড়িত Console.ReadKey। যদিও এটি সত্য যে। নেট Consoleএখানে খুব বেশি সহযোগিতা করে না, আপনি শোনার Task.Runআরও আধুনিক Asyncপদ্ধতির দিকে যেতে ব্যবহার করতে পারেন ।

সচেতন হওয়ার মূল বিষয়টি হ'ল, ডিফল্টরূপে, আপনার কনসোল থ্রেডটি Asyncঅপারেশনের জন্য সেট আপ করা হয়নি - এর অর্থ, আপনি যখন mainসম্পূর্ণরূপে অপেক্ষা Asyncকরার পরিবর্তে আপনার ফাংশনের নীচে থেকে পড়ে যান, তখন আপনার অ্যাপডোম্যান এবং প্রক্রিয়াটি শেষ হয়ে যাবে । এটিকে সম্বোধনের সঠিক উপায় হ'লAsync আপনার একক থ্রেডেড কনসোল প্রোগ্রামে সম্পূর্ণ সমর্থন প্রতিষ্ঠার জন্য স্টিফেন ক্লিয়ারির অ্যাসিঙ্ক কনটেক্সট ব্যবহার করা use তবে সহজ ক্ষেত্রে যেমন কিপ্রেসের জন্য অপেক্ষা করার মতো, একটি পূর্ণ ট্রাম্পলিন ইনস্টল করা ওভারকিল হতে পারে।

নীচের উদাহরণটি কোনও ধরণের পুনরাবৃত্ত ব্যাচ ফাইলে ব্যবহৃত কনসোল প্রোগ্রামের জন্য। এই ক্ষেত্রে, যখন প্রোগ্রামটি এর কাজটি সম্পন্ন করা হয়, সাধারণত এটি কোনও কিপ্রেসের প্রয়োজন ছাড়াই প্রস্থান করা উচিত এবং তারপরে আমরা অ্যাপটিকে প্রস্থান করতে বাধা দেওয়ার জন্য একটি alচ্ছিক কী চাপতে পারি । আমরা চক্রটি জিনিসগুলি পরীক্ষা করতে, সম্ভবত পুনরায় শুরু করতে, বা বিরতিটি একটি পরিচিত 'কন্ট্রোল পয়েন্ট' হিসাবে ব্যবহার করতে পারি যেখানে ব্যাচের ফাইলটি পরিষ্কারভাবে বিচ্ছিন্ন করতে পারে।

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
    }
}

1

নীচের কোড সহ আপনি স্পেসবার টিপতে শুনতে আপনার কনসোলের সম্পাদনের মাঝে বিরতি দিতে পারেন এবং অন্য কী টিপ না দেওয়া পর্যন্ত বিরতি দিতে হবে এবং মূল লুপটি ভাঙ্গার জন্য এস্কেপকে শুনবেন

static ConsoleKeyInfo cki = new ConsoleKeyInfo();


while(true) {
      if (WaitOrBreak()) break;
      //your main code
}

 private static bool WaitOrBreak(){
        if (Console.KeyAvailable) cki = Console.ReadKey(true);
        if (cki.Key == ConsoleKey.Spacebar)
        {
            Console.Write("waiting..");
            while (Console.KeyAvailable == false)
            {
                Thread.Sleep(250);Console.Write(".");
            }
            Console.WriteLine();
            Console.ReadKey(true);
            cki = new ConsoleKeyInfo();
        }
        if (cki.Key == ConsoleKey.Escape) return true;
        return false;
    }

-1

আমার অভিজ্ঞতা অনুসারে, কনসোল অ্যাপ্লিকেশনগুলিতে চাপা চাবির শেষ কীটি পড়ার সহজতম উপায়টি নীচে রয়েছে (তীর কীগুলির উদাহরণ সহ):

ConsoleKey readKey = Console.ReadKey ().Key;
if (readKey == ConsoleKey.LeftArrow) {
    <Method1> ();  //Do something
} else if (readKey == ConsoleKey.RightArrow) {
    <Method2> ();  //Do something
}

আমি লুপগুলি এড়াতে ব্যবহার করি, পরিবর্তে আমি কোনও পদ্ধতির মধ্যে উপরে কোডটি লিখি এবং আমি "মেথড 1" এবং "মেথড 2" উভয়ের শেষে কল করি, সুতরাং "মেথড 1" বা "মেথড 2" চালানোর পরে কনসোল.আরডকে () .কি আবার কীগুলি পড়তে প্রস্তুত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.