Something I stumbled upon in one of our projects. If you use the DispatcherTimer(TimeSpan interval, DispatcherPriority priority, EventHandler callback, Dispatcher dispatcher) ctor, Start() is automatically called. However this is the only ctor that does that, for all others you need to explicitly call Start(). Was there any reason for that?
This is the line in question:
https://github.com/dotnet/wpf/blob/master/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/DispatcherTimer.cs#L97
There is a missing code comment here that was likely cleaned during OSS prep. The gist of it is that this constructor was added due to a request (in 2003) for a behavior that functioned more like System.Threading.Timer.
I'd be hesitant to change this behavior seeing as it's been in WPF for a very long time (prior to the name of the class being DispatcherTimer). We can make breaking changes for sure in .NET 5.0, but altering this would potentially cause very subtle breaks in applications that are not easy to track down. If we're going to break behavior, it's much better to do so in a fashion that breaks at compile time or at least in very obvious ways at runtime.
We probably should file a documentation bug to more accurately describe this constructor though (and can update the comment on the constructor itself).
Yeah, changing it is out of the question obviously. What brought me to this was the the call in our codebase wasn't assigned to, so either VS (or R#?) complained that you had a non-void call but didn't assign it to a variable. Which was super confusing at first because the DispatcherTimer actually worked even though it was never explicitly started.
However changing this would probably do more harm than good, I don't know if marking it as obsolete and moving it to something like DispatcherTimer.StartNew(...) would be feasible. I was asking more out of curiosity.
It would be great if this could be added to the documentation though, I meant to mention it in the OP that I couldn't find a reason in the API docs. I'd do a PR, but I'd appreciate some help to formulate the reasoning. unless we just add something like "Note: This constructor also starts the DispatcherTimer".
I reported this a while ago as dotnet/docs#3504, but it still doesn't seem to be documented.
@BhaaLseN , thanks very much for filing that issue. I know we haven't moved it along, but I just commented on it and we'll get the fixup to the docs in. I'm going to close this and we'll track via that issue.
Most helpful comment
Yeah, changing it is out of the question obviously. What brought me to this was the the call in our codebase wasn't assigned to, so either VS (or R#?) complained that you had a non-void call but didn't assign it to a variable. Which was super confusing at first because the DispatcherTimer actually worked even though it was never explicitly started.
However changing this would probably do more harm than good, I don't know if marking it as obsolete and moving it to something like
DispatcherTimer.StartNew(...)would be feasible. I was asking more out of curiosity.It would be great if this could be added to the documentation though, I meant to mention it in the OP that I couldn't find a reason in the API docs. I'd do a PR, but I'd appreciate some help to formulate the reasoning. unless we just add something like "Note: This constructor also starts the DispatcherTimer".