Как решить быстрое закрытие программы?
Вот так можно написать класс сканер, который получает данные асинхронно. Использовать его можно таким образом в любом типе приложений. Например, в WPF приложение не будет зависать, если, скажем, запустить сканирование по клику на кнопке.

Обрати ещё внимание на метод с Task.Factory.StartNew и параметром TaskCreationOptions.LongRunning. Для сканирования папок, думаю использовать стоит.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace ConsoleApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            try
            {
                // Создаём экземпляр класса
                var scanner = new Scanner();
                // Вызываем асинхронный метод Scan, метод работает
                // какое-то время, возвращает результат.
                var data = await scanner.Scan();
                foreach (var item in data)
                {
                    // Выводим на консоль.
                    Console.WriteLine(item);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
    }

    public class Scanner
    {
        public Task<List<string>> Scan()
        {
            return Task.Run(async () =>
            {
                var results = new List<string>();

                for (int i = 0; i < 10; i++)
                {
                    // Делаем правильную задержку (имитация долгой работы для примера).
                    await Task.Delay(250);
                    // Собираем данные
                    results.Add(DateTimeOffset.Now.ToLocalTime().ToString());
                }

                return results;
            });
        }

        public async Task<List<string>> ScanVersion2()
        {
            return await Task.Factory.StartNew(async () =>
            {
                var results = new List<string>();

                for (int i = 0; i < 10; i++)
                {
                    // Делаем правильную задержку (имитация долгой работы для примера).
                    await Task.Delay(250);
                    // Собираем данные
                    results.Add(DateTimeOffset.Now.ToLocalTime().ToString());
                }

                return results;
            }, TaskCreationOptions.LongRunning)
                .Unwrap() // Без этого возвращается Task<List<string>>, а не List<string>
                .ConfigureAwait(false);
        }
    }
}

Стоит почитать книгу "Конкурентность в C#. Асинхронное, параллельное и многопоточное программирование"
Скриншот сделан с видео: https://youtu.be/lh8cT6qI-nA?t=1123


Изучи как работает Main() и тебе всё станет ясно
Книжки читал?