For PeriodicTimer (AsyncTimer at the time), regarding WaitForNextTickAsync, David Fowler mentioned "The execution context isn't captured" (here) via (here). However, given that was not necessarily the final implementation, I reviewed the PeriodicTimer documentation which makes no mention of context capturing.
Based on Stephen Toub's decade old, but still excellent, "The Task-based Asynchronous Pattern," and the following code:
private CancellationTokenSource tokenSource;
private async void start_Click(object sender, EventArgs e)
{
tokenSource = new CancellationTokenSource();
var second = TimeSpan.FromSeconds(1);
using var timer = new PeriodicTimer(second);
try
{
while (await timer.WaitForNextTickAsync(tokenSource.Token).ConfigureAwait(false))
{
if (txtMessages.InvokeRequired)
{
txtMessages.Invoke(() => txtMessages.AppendText("Invoke Required..." + Environment.NewLine));
}
else
{
txtMessages.AppendText("Invoke NOT Required!" + Environment.NewLine);
}
}
} catch (OperationCanceledException)
{
//disregard the cancellation
}
}
private void stop_Click(object sender, EventArgs e)
{
tokenSource.Cancel();
}
If ConfigureAwait is passed true (or removed entirely), my output is as follows:
Invoke NOT Required!
Invoke NOT Required!
Invoke NOT Required!
Invoke NOT Required!
...
However, if ConfigureAwait is passed false, my output is as follows:
Invoke Required...
Invoke Required...
Invoke Required...
Invoke Required...
...
Unless I'm confusing SynchronizationContext with "executing thread," it seems like the current SynchronizationContext IS captured by default. Can anyone (maybe one of the greats) please clarify?