Параллельное выполнение задач может занимать много времени. И иногда может возникнуть необходимость прервать выполняемую задачу. Для этого платформа .NET предоставляет структуру CancellationToken из пространства имен System.Threading .
Общий алгоритм отмены задачи обычно предусматривает следующий порядок действий:
- Создание объекта CancellationTokenSource , который управляет и посылает уведомление об отмене токену.
- С помощью свойства CancellationTokenSource.Token получаем собственно токен — объект структуры CancellationToken и передаем его в задачу, которая может быть отменена.
CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token;
Для передачи токена в задачу можно применять один из конструкторов класса Task:
CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token; Task task = new Task(() => < выполняемые_действия>, token); //
Теперь касательно третьего пункта — определения действий отмены задачи. Как именно завершить задачу? Конкретные действия на лежат целиком на разработчике, тем не менее есть два общих варианта выхода:
Use C# in VS Code!
- При получении сигнала отмены выйти из метода задачи, например, с помощью оператора return или построив логику метода соответствующим образом. Но следует учитывать, что в этом случае задача перейдет в состояние TaskStatus.RanToCompletion , а не в состояние TaskStatus.Canceled .
- При получении сигнала отмены сгенерировать исключение OperationCanceledException , вызвав у токена метод ThrowIfCancellationRequested() . После этого задача перейдет в состояние TaskStatus.Canceled .
Мягкий выход из задачи без исключения OperationCanceledException
Сначала рассмотрим первый — «мягкий» вариант завершения:
CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token; // задача вычисляет квадраты чисел Task task = new Task(() => < for (int i = 1; i < 10; i++) < if (token.IsCancellationRequested) // проверяем наличие сигнала отмены задачи < Console.WriteLine(«Операция прервана»); return; // выходим из метода и тем самым завершаем задачу >Console.WriteLine($»Квадрат числа равен «); Thread.Sleep(200); > >, token); task.Start(); Thread.Sleep(1000); // после задержки по времени отменяем выполнение задачи cancelTokenSource.Cancel(); // ожидаем завершения задачи Thread.Sleep(1000); // проверяем статус задачи Console.WriteLine($»Task Status: «); cancelTokenSource.Dispose(); // освобождаем ресурсы
В данном случае задача task вычисляет и выводит на консоль квадраты чисел от 1 до 9. Для отмены задачи нам надо создать и использовать токен. Вначале создается объект CancellationTokenSource :
CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
Затем из него получаем сам токен:
Folders & files in VS Code made super fast like this!
CancellationToken token = cancelTokenSource.Token;
Чтобы отменить операцию, необходимо вызвать метод Cancel() у объекта CancellationTokenSource:
cancelTokenSource.Cancel();
В данном случае отмена задачи вызывается через секунду, чтобы задача произвела некоторые действия.
В самом методе задачи в цикле мы можем отловить сигнал отмены с помощью проверки свойства token.IsCancellationRequested :
if (token.IsCancellationRequested)
Если был вызван метод cancelTokenSource.Cancel() , то выражение token.IsCancellationRequested возвращает true.
После завершения задачи проверяем ее статус:
Console.WriteLine($»Task Status: «);
Поскольку задача успешно завершена, у задачи должен быть статус RanToCompletion
И в конце у объекта CancellationTokenSource вызываем метод Dispose:
cancelTokenSource.Dispose();
Консольный вывод программы:
Квадрат числа 1 равен 1 Квадрат числа 2 равен 4 Квадрат числа 3 равен 9 Квадрат числа 4 равен 16 Квадрат числа 5 равен 25 Операция прервана Task Status: RanToCompletion
Отмена задачи с помощью генерации исключения
Второй способ завершения задачи представляет генерация исключения OperationCanceledException . Для этого применяется метод ThrowIfCancellationRequested() объекта CancellationToken:
CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token; Task task = new Task(() => < for (int i = 1; i < 10; i++) < if (token.IsCancellationRequested) token.ThrowIfCancellationRequested(); // генерируем исключение Console.WriteLine($»Квадрат числа равен «); Thread.Sleep(200); > >, token); try < task.Start(); Thread.Sleep(1000); // после задержки по времени отменяем выполнение задачи cancelTokenSource.Cancel(); task.Wait(); // ожидаем завершения задачи >catch (AggregateException ae) < foreach (Exception e in ae.InnerExceptions) < if (e is TaskCanceledException) Console.WriteLine(«Операция прервана»); else Console.WriteLine(e.Message); >> finally < cancelTokenSource.Dispose(); >// проверяем статус задачи Console.WriteLine($»Task Status: «);
Здесь опять же проверяем значение свойства IsCancellationRequested, и если оно равно true, генерируем исключение:
if (token.IsCancellationRequested) token.ThrowIfCancellationRequested(); // генерируем исключение
Чтобы обработать исключение, помещаем весь код работы с задачей в конструкцию try..catch и также с помощью вызова cancelTokenSource.Cancel() посылаем сообщение об отмене задачи.
Стоит отметить, что генерируемое исключение будет спрятано в объекте AggregateException, который по сути представляет набор исключений. Если причина исключения состояла в отмене задачи, то мы можем найти в этом наборе исключений исключение типа TaskCanceledException
catch (AggregateException ae) < foreach (Exception e in ae.InnerExceptions) < if (e is TaskCanceledException) Console.WriteLine(«Операция прервана»); else Console.WriteLine(e.Message); >>
Класс TaskCanceledException является производным от OperationCanceledException. Исключение типа TaskCanceledException возникает, если для задачи устанавливается статус Canceled .
Консольный вывод программы:
Квадрат числа 1 равен 1 Квадрат числа 2 равен 4 Квадрат числа 3 равен 9 Квадрат числа 4 равен 16 Квадрат числа 5 равен 25 Операция прервана Task Status: Canceled
Стоит отметить, что исключение возникает только тогда, когда мы останавливаем текущий поток и ожидаем завершения задачи с помощью методов Wait или WaitAll. Если эти методы не используются для ожидания задачи, то для нее просто устанавливается состояние Canceled. Например, в следующем случае исключение не возникнет:
CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token; Task task = new Task(() => < for (int i = 1; i < 10; i++) < if (token.IsCancellationRequested) token.ThrowIfCancellationRequested(); // генерируем исключение Console.WriteLine($»Квадрат числа равен «); Thread.Sleep(200); > >, token); try < task.Start(); Thread.Sleep(1000); // после задержки по времени отменяем выполнение задачи cancelTokenSource.Cancel(); // ожидаем завершения задачи Thread.Sleep(1000); >catch (AggregateException ae) < foreach (Exception e in ae.InnerExceptions) < if (e is TaskCanceledException) Console.WriteLine(«Операция прервана»); else Console.WriteLine(e.Message); >> finally < cancelTokenSource.Dispose(); >// проверяем статус задачи Console.WriteLine($»Task Status: «);
Консольный вывод программы:
Квадрат числа 1 равен 1 Квадрат числа 2 равен 4 Квадрат числа 3 равен 9 Квадрат числа 4 равен 16 Квадрат числа 5 равен 25 Task Status: Canceled
Регистрация обработчика отмены задачи
Выше для проверки сигнала отмены применялось свойство IsCancellationRequested. Но есть и другой способ узнать о том, что был послан сигнал отмены задачи. Метод Register() позволяет зарегистрировать обработчик отмены задачи в виде делегата Action:
CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token; // задача вычисляет квадраты чисел Task task = new Task(() => < int i = 1; token.Register(() =>< Console.WriteLine(«Операция прервана»); i = 10; >); for (; i < 10; i++) < Console.WriteLine($»Квадрат числа равен «); Thread.Sleep(400); > >, token); task.Start(); Thread.Sleep(1000); // после задержки по времени отменяем выполнение задачи cancelTokenSource.Cancel(); // ожидаем завершения задачи Thread.Sleep(1000); // проверяем статус задачи Console.WriteLine($»Task Status: «); cancelTokenSource.Dispose(); // освобождаем ресурсы
Здесь обработчик отмены представлен лямбда-выражением:
token.Register(() => < Console.WriteLine(«Операция прервана»); i = 10; >);
Поскольку действие задачи представляет цикл, который выполняется при значении i меньше 10, то установка этой переменной в обработчике отмены приведет к выходу из цикла и соответственно завершению задачи.
Передача токена во внешний метод
Если операция, которая выполняется в задаче, представляет внешний метод, то ему можно передавать в качестве одного из параметров:
CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token; Task task = new Task(() =>PrintSquares(token), token); try < task.Start(); Thread.Sleep(1000); // после задержки по времени отменяем выполнение задачи cancelTokenSource.Cancel(); // ожидаем завершения задачи task.Wait(); >catch (AggregateException ae) < foreach (Exception e in ae.InnerExceptions) < if (e is TaskCanceledException) Console.WriteLine(«Операция прервана»); else Console.WriteLine(e.Message); >> finally < cancelTokenSource.Dispose(); >// проверяем статус задачи Console.WriteLine($»Task Status: «); void PrintSquares(CancellationToken token) < for (int i = 1; i < 10; i++) < if (token.IsCancellationRequested) token.ThrowIfCancellationRequested(); // генерируем исключение Console.WriteLine($»Квадрат числа равен «); Thread.Sleep(200); > >
Отмена параллельных операций Parallel
Для отмены выполнения параллельных операций, запущенных с помощью методов Parallel.For() и Parallel.ForEach() , можно использовать перегруженные версии данных методов, которые принимают в качестве параметра объект ParallelOptions . Данный объект позволяет установить токен:
CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token; // в другой задаче посылаем сигнал отмены new Task(() => < Thread.Sleep(400); cancelTokenSource.Cancel(); >).Start(); try < Parallel.ForEach(new List() < 1, 2, 3, 4, 5>, new ParallelOptions < CancellationToken = token >, Square); // или так //Parallel.For(1, 5, new ParallelOptions < CancellationToken = token >, Square); > catch (OperationCanceledException) < Console.WriteLine(«Операция прервана»); >finally < cancelTokenSource.Dispose(); >void Square(int n) < Thread.Sleep(3000); Console.WriteLine($»Квадрат числа равен «); >
В параллельной запущенной задаче через 400 миллисекунд происходит вызов cancelTokenSource.Cancel() , в результате программа выбрасывает исключение OperationCanceledException, и выполнение параллельных операций прекращается.
Источник: metanit.com
Блог
Visual Studio 2019: останавливать отладчик при закрытии окна браузера, но НЕ закрывать браузер при остановке отладки
- Post author: admin
- Запись опубликована: 12 декабря, 2022
- Post category: Вопросы по программированию
#visual-studio #debugging
#visual-studio #отладка
Вопрос:
Если я закрою браузер, в котором запущено веб-приложение, желательно, чтобы сеанс отладки прекратился. В конце концов, это равносильно закрытию приложения Windows. Однако, если я остановлю отладку, а в браузере будет несколько вкладок (как это часто бывает), все они закроются — определенно не то, что я предполагал. Неиспользование этой опции означает, что я постоянно забываю о запущенном отладчике, а нажатие кнопки остановки — это просто дополнительная работа.
Есть ли дополнение к Visual Studio или какой-либо другой трюк, позволяющий выполнять только первое: останавливать отладчик при закрытии окна?
Кто подумал, что было бы неплохо поместить два параметра за один флажок? Это палка о двух концах в самом остром виде!
Ответ №1:
Это не совсем то, что вы хотите. Но это может быть обходным путем. Если вы включите отладку JavaScript в Tools-> Options-> Debugging, а затем отладите-> Отсоедините все. Браузер должен оставаться открытым, и отладка должна прекратиться… Теперь это будет означать, что приложение все еще запущено, что может быть нежелательно.
Это отличное предложение, чтобы сделать это опцией. Я бы посоветовал вам открыть предложение в сообществе разработчиков.
Источник: programbox.ru
Сочетания клавиш в Visual Studio
Visual Studio — очень популярный инструмент программирования, потому что он был разработан Microsoft «гигантом» с приятным дружественным интерфейсом. Чтобы помочь в процессе «кодирования», использование сочетаний клавиш поможет вам несколько сократить время и «избыточные» операции.
Предлагаем вам прочитать и обратиться к важной таблице сочетаний клавиш в Visual Studio ниже.
1. Горячие клавиши для управления кодом
Удалить строку кода в позиции курсора
Ctrl + Shift + клавиша)
Выделите командную строку для (), writereln ().
Выделите от позиции курсора до начала строки
Выделите от позиции курсора до конца строки
Искать в разделе «Решение»
Поиск по ссылке на переменную, метод, класс. проекта.
Поиск по ссылке на переменную, метод, класс. проекта
Поменяйте строку на нижнюю
Alt + Shift + F10 + Enter
Переименовывайте переменные и функции одновременно при изменении имен переменных и функций. Реализовать унаследованный абстрактный класс или интерфейсный метод
область инкапсулированных данных
2. Ярлык навигации.
Клавиши со стрелками ←
Переместить на 1 символ влево
Клавиши со стрелками →
Переместить 1 символ вправо
Клавиши со стрелками ↑
Перейти в верхнюю строку
Клавиши со стрелками ↓
Перейти к нижней строке
Ctrl + клавиша со стрелкой ←
Двигаться влево на 1 слово
Ctrl + клавиша со стрелкой →
Переместить вправо на 1 слово
Ctrl + клавиша со стрелкой ↑
Ctrl + клавиша со стрелкой ↓
Двигаться вниз строка за строкой
Перейти к началу строки
Перейти в конец строки
Подведите курсор к началу страницы
Перемещает курсор в нижнюю часть страницы
Верните курсор в начало страницы
Вернуть курсор на позицию страницы
Отображение диалогового окна GoTo Line
Заполните недостающий элемент в фигурных скобках <>
Создавать, удалять закладки
Перейти к следующей закладке
Перейти к закладке вперед
Удалить все закладки
3. Выбор ярлыка
Shift + клавиша со стрелкой ←
Расширить выделение одним символом слева
Shift + клавиша со стрелкой →
Расширить выделение одним символом справа
Shift + клавиша со стрелкой ↑
Расширить выделение на 1 строку выше
Shift + клавиша со стрелкой ↓
Разверните выделение на 1 строку ниже
Ctrl + Shift + клавиша со стрелкой ←
Расширить выделение одним словом слева
Ctrl + Shift + стрелка →
Разверните выделение на 1 слово вправо
Разверните выделение в верхнюю часть страницы
Разверните выделение до низа страницы
Ctrl + Shift + Home
Разверните выделение в верхнюю часть страницы
Ctrl + Shift + Конец
Разверните выделение до низа страницы
Выбрать всю страницу
Выбрать текущее слово в позиции курсора
Переключить вертикальный вид => горизонтальный
4. Свойства окна ярлыков
Показать документацию в диалоговом окне «Свойства»
Клавиши со стрелками ← или клавиши —
Закройте кнопку в списке свойств
Клавиша со стрелкой → или + клавиша
Открыть 1 кнопку в списке свойств
Закройте окно свойств
+ Ключ на цифровой клавиатуре
Разверните кнопку 1 и отобразите детали в списке свойств.
Ключ — на Numpad
Записать узел в список свойств
Прокрутите список свойств
Перемещение вверх по списку свойств
Клавиши со стрелками ↑
Перемещение вверх по списку свойств
Клавиши со стрелками ↓
Прокрутите список свойств
Перемещение между окном настроек и объектом
Перейти к первой собственности в списке
Прокрутите вниз до последней собственности в списке
5. Сочетание клавиш с полем настроек.
Ctrl + C
Ctrl + Insert
Ctrl + X
Shift + Удалить
Поменяйте местами два случайных символа. Например: AD — CB в AB — CD.
Поменять местами слова, соединенные оператором слова
Поменять местами 2 строки
Преобразовать выделенный текст => нижний регистр
Преобразует выделенный текст в верхний регистр
Показать или скрыть белые символы
Заменить пробелы табуляцией
Заменить табуляцию пробелами
Переместите курсор вправо еще на 1 вкладку
Переместите курсор влево еще на 1 вкладку
6. Сочетание клавиш с отладкой
Откройте системное меню
Добавить и удалить разрывы строк
Ctrl + Shift + F9
Удалить разрывы строк
Отключить разрывы строк
Отобразить окно Авто
Отобразить окно точки останова
Отображение окна стека вызовов
Отобразить окно немедленного выполнения
Отображает окно «Локальные»
Отобразить окно бегущего документа
Показать следующую команду
Благодаря встроенным сочетаниям клавиш в версиях Visual Studio читатели могут быстрее управлять сочетанием клавиш в статье. Удачи!
Источник: snaptik.ru