#c_sharp #tpl #task
Почему CancellationToken реализован как структура? Ведь структура является типом значения, как тогда реализован данный механизм? static void Main(string[] args) { CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); CancellationToken token = cancelTokenSource.Token; Task task1 = new Task(() => Factorial(5, token)); task1.Start(); cancelTokenSource.Cancel(); } static void Factorial(int x, CancellationToken token) { int result = 1; for (int i = 1; i <= x; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Операция прервана токеном"); return; } result *= i; Console.WriteLine("Факториал числа {0} равен {1}", i, result); Thread.Sleep(5000); } } Ведь структура является типом значения и создается копия объекта при передачи параметра CancellationToken token
Ответы
Ответ 1
Почему CancellationToken реализован как структура? Для борьбы за эффективность. В большинстве случаев, да, CancellationToken вполне мог бы быть и классом, одна аллокация ничего не меняет, так как многопоточный код обычно некритичен к паре лишних мелких аллокаций. Но ведь CancellationToken задумывался как общий механизм отмены. И существуют случаи, в которых аллокации критичны для пользователей. Если бы CancellationToken был классом, то в этих случаях пользователям фреймворка проходилось бы пользоваться самописной структурой, и, хуже того, они не смогли бы пользоваться библиотечными методами. (Например, если пользователь хочет в метод, который ожидает CancellationToken, передать CancellationToken.None, потому что ему нужна скорость и не нужна отмена.) Так что разработчики решили облегчить нам, пользователям, жизнь, и сделали CancellationToken таки структурой. По поводу реализации механизма: да, разработчики нарушили семантику, и CancellationToken ведёт себя как типичный класс, а не как типичная структура. Они реализовали это таким образом. В CancellationToken есть единственное поле private CancellationTokenSource m_source; (ссылка на исходники). В проверке на равенство сравнивается m_source, и при копировании m_source копируется тоже, так что копия токена ведёт себя как оригинал, и тем самым неотличима от него. В частности, если оригинал токена отменён, то его копия — тоже.
Комментариев нет:
Отправить комментарий