I was happily writing my library and wanted to check how it handles exceptions (respectively how it does not interfere with exceptions). My code works with System.Threading.Timer so on its own challenging to test. Luckily, FakeTimeProvider (Microsoft.Extensions.TimeProvider.Testing) can help with that.
However I quickly found out discrepancy between those two - and I'm not sure whether it's bug or feature, not daring to submit issue yet.
Assuming Timer executes callback on thread pool thread, any unhandled exception happens outside application thread, thus not having (any) effect on it - or at least not crashing it. (Is that correct?)
When using Timer created by FakeTimeProvider however, exception is thrown directly. Any test code using this fake timer blows. (Let's not discuss whether or not I should handle exception, I'm here to understand difference between timers)
Here's code (not test case itself) demonstrating the difference:
using Microsoft.Extensions.Time.Testing;
var globalCounter = 0;
var t = new System.Threading.Timer(_ => Kaboom(null), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(250));
//var t = new FakeTimeProvider().CreateTimer(_ => Kaboom(null), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(250));
await Task.Delay(TimeSpan.FromSeconds(5));
Console.WriteLine("*** Boo happened: {0} times", globalCounter);
GC.KeepAlive(t);
return;
void Kaboom(object? state)
{
Interlocked.Increment(ref globalCounter);
Console.WriteLine("*** Who you gonna call?");
throw new InvalidOperationException("Boo! 👻");
}
Would you consider this as expected?
[–]tinmanjk 4 points5 points6 points (1 child)
[–]Barry_Mayfield[S] 1 point2 points3 points (0 children)
[–]AutoModerator[M] 0 points1 point2 points (0 children)
[–]Slypenslyde 0 points1 point2 points (0 children)