Зарегистрированная отмена заказа на обратный вызов - PullRequest
0 голосов
/ 12 января 2019

Если я зарегистрирую некоторые обратные вызовы на CancellationToken до его отмены, кажется, что они будут вызваны в обратном порядке , когда токен будет отменен. Гарантирован ли этот порядок вызова?

var cts = new CancellationTokenSource();
var token = cts.Token;
token.Register(() => Console.WriteLine("1"));
token.Register(() => Console.WriteLine("2"));
token.Register(() => Console.WriteLine("3"));
cts.Cancel();

Это выдаст

3
2
1

1 Ответ

0 голосов
/ 12 января 2019

Ну, из исходного кода класса CancellationToken вроде бы так. Метод ExecuteCallbackHandlers(bool throwOnFirstException) отвечает за получение обратных вызовов и их выполнение. Содержит этот фрагмент кода:

try
{
   for (int index = 0; index < callbackLists.Length; index++)
   {
      SparselyPopulatedArray<CancellationCallbackInfo> list = Volatile.Read<SparselyPopulatedArray<CancellationCallbackInfo>>(ref callbackLists[index]);
      if (list != null)
      {
         SparselyPopulatedArrayFragment<CancellationCallbackInfo> currArrayFragment = list.Tail;

         while (currArrayFragment != null)
         {
             for (int i = currArrayFragment.Length - 1; i >= 0; i--)
             {
                ... some other code
             }
        }
     }
   }
}

Во внутреннем цикле for он переходит фрагмент массива обратных вызовов назад от последнего к первому элементу.

Однако, как отмечает @Nick, это не гарантируется в документации. Простым решением было бы добавить обратные вызовы в один делегат - таким образом мы имеем больше контроля над порядком выполнения:

token.Register(() => 
{ 
   Console.WriteLine("1"));
   Console.WriteLine("2"));
   Console.WriteLine("3"));
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...