пытается понять, как работает Task.ContinueWith
Лучше просто игнорировать ContinueWith
и использовать вместо него await
.Но, если вы хотите изучить низкоуровневый, опасный способ сделать что-то, то я обязуюсь.Пожалуйста, не используйте в производстве.
Первое, на что нужно обратить внимание, это то, что ContinueWith
всегда планирует работу в планировщике задач.И он не использует планировщик задач по умолчанию;по умолчанию используется планировщик задач current .Предполагая, что HandleButtonClick
вызывается непосредственно вашей структурой пользовательского интерфейса (а не, например, запланировано с помощью планировщика задач), тогда нет текущего планировщика задач, поэтому ContinueWith
будет использовать планировщик задач по умолчанию, который является задачей пула потоковпланировщик.Чтобы избежать такого рода запутанных рассуждений, код должен всегда передавать TaskScheduler
в ContinueWith
.
Следующее, что следует отметить, это то, что ContinueWith
не понимает async
делегатов,Что касается этого, async
лямбда - это просто причудливый способ дать ему Func<Task>
делегат, а ContinueWith
заботится только о начальной синхронной части этого метода.
Последнее, что нужно сделатьобратите внимание, что потоки пула потоков считаются взаимозаменяемыми.Это верно для любого async
/ await
кода;если он работает в контексте пула потоков и выполняет await
, он может возобновить выполнение в любом потоке пула потоков.Это может быть или не быть тем потоком, в котором выполнялся код до await
.