Держите консоль открытой, не прерывая другие функции - PullRequest
0 голосов
/ 28 апреля 2020

Как сохранить консольное приложение открытым, даже если все ожидаемые события завершены, но не прерывая другие возможные ожидаемые значения?

Я знаю, что мой вопрос звучит странно, но просто для объяснения:

Я используя библиотеку Telegram.Bot, и мне нужно прослушать все входящие обновления из telegram. Проблема в том, что как только я установил обработчик обновлений, консоль просто закрывается.

Еще одна вещь, которая у меня есть, это запрос с использованием RestSharp, который получает json от API каждые x минут, который выполняет работу, сохраняя консоль жива, потому что я использую способ обнаружения отмены консоли перед прерыванием l oop.

Есть ли еще лучший способ сделать то, что я хочу?

Это то, что я ' Я использую для прослушивания закрытия консоли { ссылка }

И у меня есть exitSystem в качестве переменной некоторое время l oop

while (!exitSystem)
     // Do this

1 Ответ

3 голосов
/ 28 апреля 2020

Использование while l oop не приведет к ненужной трате циклов ЦП, потому что все, что вы хотите сделать, это ждать сигнала на выход. Вы можете ожидать события завершения задачи асинхронно, используя TaskCompletionSource. Ниже приведен код, который дает вам представление о том, как его реализовать.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp
{
    public class Program
    {
        private static readonly TaskCompletionSource<object> TaskCompletionSrc = new TaskCompletionSource<object>();
        static async Task<int> Main(string[] args)
        {
            Console.WriteLine("Launching background tasks...");
            var thread = new Thread(DoSomethingInBackground);
            thread.Start();

            //wait for the task completion event
            await TaskCompletionSrc.Task;

            Console.WriteLine("Task completed. Exiting...");
            return 0;
        }

        private static void DoSomethingInBackground()
        {
            Thread.Sleep(5000);
            //signal that task has completed
            TaskCompletionSrc.SetResult(null);
        }
    }
}

Обновленный ответ:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp
{
    public class Program
    {
        //API call interval in milliseconds
        private const int ApiCallIntervalMilliSeconds = 5000;
        public static void Main(string[] args)
        {

            //create token source for cancelling the background operations when the main thread exists
            using (var cancellationTokenSrc = new CancellationTokenSource())
            //create timer which triggers the MakeApiCallback immediately and repeats for every specified milliseconds
            using (var timer = new Timer(TriggerApiCall, cancellationTokenSrc, TimeSpan.Zero,
                TimeSpan.FromMilliseconds(ApiCallIntervalMilliSeconds)))
            {
                Console.WriteLine("Program is running. Press any to exit...");

                //blocks the main thread from running to completion
                Console.Read();

                //key press, cancel any API calls in progress
                cancellationTokenSrc.Cancel();
            }

        }

        public static async void TriggerApiCall(object argument)
        {
            var tokenSrc = (CancellationTokenSource) argument;
            await MakeApiCall(tokenSrc.Token);
        }


        private static async Task MakeApiCall(CancellationToken cancellationToken)
        {
            Console.WriteLine("API Call in progress...");
            try
            {
                //simulate the background work
                await Task.Delay(3000, cancellationToken);
            }
            catch (TaskCanceledException)
            {
                Console.WriteLine("API call cancelled!");
                return;
            }
            catch(Exception ex)
            {
                Console.WriteLine("API call failed. Exception:" + ex);
                return;
            }

            Console.WriteLine("API call completed successfully.");
        }
    }
}
...