Nito.AsyncEx vs DotNext.Threading
We're currently searching for a nice AsyncAutoResetEvent implementation. We found two suitable implementations:
Nito.AsyncEx: https://github.com/StephenCleary/AsyncEx/blob/master/doc/AsyncAutoResetEvent.md
DotNext.Threading: https://dotnet.github.io/dotNext/api/DotNext.Threading.AsyncAutoResetEvent.html
Is there any comparison between those, or between the two libraries in general?
(PS: We do not want to use the Microsoft.VisualStudio.Threading implementation of AsyncAutoResetEvent, as that package pulls in analyzers which just don't apply in our environment, as our project is not a VS extension.)
GitHub
AsyncEx/doc/AsyncAutoResetEvent.md at master · StephenCleary/AsyncEx
A helper library for async/await. Contribute to StephenCleary/AsyncEx development by creating an account on GitHub.
9 Replies
Hm, we are using the MS nuget package you mentioned
You can also use it in non-VS extensions
I don't think there is a way to get rid of the analyzers but you could always silence them. We suppressed two of the rules, the rest seemed pretty solid for our use case (backend service)
It's important to note that the vsthreading analyzers are much more general than vs. The name isn't good, I agree, but they're for more than it implies
The most annying one is the one which requires all async xunit test methods to have the ...Async suffix in their name.
While we prefer this name convention for normal code, we do not want it in test methods, as the Async is a detail of the test implementation and should not appear in reports, and the test identifier should not change just because the implementation now needs to use async. Other analyzers have an exception for those test methods.
Another annoying one is the analyzer which suggests to use JoinableTaskFactory when accessing Task.Result, even if it's in an if block where Task.IsComplete is checked. And, as far as I can see, the JoinableTaskFactory has quite some overhead, which is required in a WPF or WinForms Environment with a primary thread, but doesn't make sense in a ThreadPool environment like ASP.NET Core.
There was some other cases which we didn't like but they were single occurrences.
What annoys us most is that the implementation package pulls in the analyzer unconditionally - our policy prefers to explicitly decide about the rule set. So we started looking for alternatives, and both mentioned above seem to be stable and maintained.
Yeah, we suppressed the first rule you mentioned
Couldn't you just use the MS nuget package and literally suppress every rule?
I guess we could. However, some guys in the QA area are a bit picky about suppressing rules, we need to give justifications. And it's inefficient to run analyzers just to completely ignore them. 🙂
I wonder what drove the maintainers to implicitly pull in the analyzers, instead of providing them optionally (as e. g. xUnit Analyzers do).
True, not really a big fan of that either. I assume that decision was appropriate for their MS projects
https://github.com/microsoft/vs-threading/issues/605#issuecomment-611215842
Ouch. We also use StreamJsonRpc. That might mean replacing the library above may not actually solve the problem. 🥴
We don't run the analysis if they can't produce observable results, fwiw
(roslyn doesn't, I mean, in case that wasn't clear)
Next case:
VSTHRD003: Avoid awaiting or returning a Task representing work that was not started within your context as that can lead to deadlocks. Start the work within this context, or use JoinableTaskFactory.RunAsync to start the task and await the returned JoinableTask instead.As far as I can see, this only applies in single threaded environments like Windows Forms or WPF, not in a free threaded environment running on the thread pool. And we sometimes store or pass some tasks around, as a kind of "promise" for a future result of an operation. For your info: we will go with suppressing the warnings now, as we cannot easily get rid of the dependency anyways.