Live data from Hacker News

Beware of “async void” in C#

theburningmonk.com

11–20 of 24 posts

Re: Beware of “async void” in C#

#11
post #8
post #6

To be a bit facetious: remember that an unhandled exception in your main program thread will also crash your program. The article holds a very valuable lesson, though: just because you don't see "Task" doesn't mean that there aren't threads involved. In this way `async void` is deceptive but is certainly not something that is broken or something that you should never use. There is actually a case where an exception i…

On a related note, I really dislike the dispatcher paradigm, especially with the inclusion of async-await. For good performance of IO async calls you usually want to call .ConfigureWait(false), otherwise it will wait for the UI context to switch back to, you might even risk thread starvation. But now each async call is a potential switch out of the UI thread and certain crasch down the road, meaning you have to put D…

> the dispatcher paradigm is one of the thing I dislike the most about coding UI stuff in .Net

It inherits it from Windows. As far as I know, most GUIs have a dispatcher because . I definitely think that there could have been a better way to solve the problem (method interception), however, I think that TPL does add value.

In your case you cited intense IO as one reason to call `.ConfigureAwait(false).` The thing is: you have made a conscious decision to not return to the UI thread and therefore are more likely to tread carefully when writing the remainder of the method. `.ConfigureAwait(false)` declares "dragons be here."

Previously someone who didn't know better would update the UI from the wrong thread, weird things happen and they don't know why.

Here's something to make things simpler for you: https://gist.github.com/jcdickinson/f875229e671710cf1b34

Re: Beware of “async void” in C#

#12
This is a rough one, because while Microsoft's own docs tell you not to use async void, all of their demo code that I've seen does.

Granted, it's demo code and not production code, but less experienced developers do not always pick up on that.

Re: Beware of “async void” in C#

#13
post #11
post #8

Earlier quoted context omitted.

On a related note, I really dislike the dispatcher paradigm, especially with the inclusion of async-await. For good performance of IO async calls you usually want to call .ConfigureWait(false), otherwise it will wait for the UI context to switch back to, you might even risk thread starvation. But now each async call is a potential switch out of the UI thread and certain crasch down the road, meaning you have to put D…

> the dispatcher paradigm is one of the thing I dislike the most about coding UI stuff in .Net It inherits it from Windows. As far as I know, most GUIs have a dispatcher because . I definitely think that there could have been a better way to solve the problem (method interception), however, I think that TPL does add value. In your case you cited intense IO as one reason to call `.ConfigureAwait(false).` The thing is:…

> It inherits it from Windows. As far as I know, most GUIs have a dispatcher because .

This is a kind of lame elision. The classical Windows UI threading model is that every window has an owning thread [the thread it was created on], and that owning thread is supposed to drain its message queue periodically. You can send messages to another thread's object [either in blocking, via SendMessage, or enqueue without blocking for result, via PostMessage].

Re: Beware of “async void” in C#

#14
post #9

Async void methods are for asynchronous event handlers. [1] That's an unfortunate consequence of the way event handlers work in C# (event handlers that return a type don't work well in the language). Any other use of async void is incorrect; if you see an async void method in any other context, replace it with async Task. (Would be nice if calling an async void method directly threw a compiler warning to make this co…

"Would be nice if calling an async void method directly threw a compiler warning to make this completely clear." With VS 2015 and Roslyn, you can easily achieve this. In fact, there's already sample code to do this in the roslyn samples project[0]. [0] https://github.com/dotnet/roslyn/tree/master/src/Samples/CSh...

The ability to write my own analyzers shouldn't be a substitute for a well-curated set of code analysis checks out of the box, though. I want to spend my time building my product, not building the tooling so I can build my product.

(Note that I haven't had the opportunity to play with VS2015 yet; for all I know, these checks from the Roslyn samples might already be provided with the IDE.)

Re: Beware of “async void” in C#

#15
post #2

To make it perfectly clear , "async void" should be replaced with "async Task" The async stuff is interesting in that akin to generics it has an almost cancerous effect on your code. When you start using them they tends to spread to large parts of your code base if you're not careful. It's awesome that C# now has such good support for parallelism and asynchronicity... but I remain in the opinion that a lot of this st…

Here's a nice article to describe that transitive effect.

http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y...

Also applies to IDisposable etc.

Re: Beware of “async void” in C#

#16
post #3

The article is not strictly correct. A more detailed explanation can be found here: https://msdn.microsoft.com/en-us/magazine/jj991977.aspx Exceptions actually bubble up to the active SynchronizationContext, and won't necessarily kill your process. In ASP.Net, aborting a request on an error is often desired behavior. Still generally good advice though. Issues arising from accidental async void use are often very tric…

It looks like the article was written in 2012 where the crashing behaviour was normal in Windows 8.0, this changed in Windows 8.1

Re: Beware of “async void” in C#

#17
post #10

Earlier quoted context omitted.

I've been pleasantly surprised by the async workflows in F#. Behind the scenes it is one big ass monadic construct that has been grafted onto the language, but it doesn't feel that way at all when you use it...it is incredibly elegant and easy to read/write and understand exactly what is happening in terms of control flow. I think it is perfectly possible for C# to improve it without starting over from scratch, simpl…

Yeah, but the problem with C# is not that it isn't working, and it is pretty legible and easy to understand. The problem is the syntax and lack of some abstractions. F# syntax is probably more suited for a certain style of programming. You could try to rework C# without concern for breaking current behavior and making it more cohesive and consistent... but at that point it won't be C# I think. What I'd really like th…

What you describe really sounds like functional programming.

Re: Beware of “async void” in C#

#18
post #10

Earlier quoted context omitted.

Yeah, but the problem with C# is not that it isn't working, and it is pretty legible and easy to understand. The problem is the syntax and lack of some abstractions. F# syntax is probably more suited for a certain style of programming. You could try to rework C# without concern for breaking current behavior and making it more cohesive and consistent... but at that point it won't be C# I think. What I'd really like th…

What you describe really sounds like functional programming.

Yes, it's probably closer to functional programming than OOP, but I feel that strict functional programming doesn't adapt well to some use-cases, and there really needs to be a modular model involved as well. I think a new mainstream language would be best to be a hybrid of some sort.

Re: Beware of “async void” in C#

#19
For completeness, isn't there a third option of ensuring you're catching and handling all exceptions in an async void handler?

   private static async void OnTimerFired(object sender, ElapsedEventArgs args)

   {
	Exception exception = null;
	try
	{
		await Task.Delay(1000);

		// this is NOT going to terminate your process!
		throw new Exception();
	}
	catch (Exception ex)
	{
	  exception = ex;
	}

	if (exception != null)
	{
	  ...
	}
  }
And in C#6 you can await in catch or finally blocks, so this gets even simpler.

Re: Beware of “async void” in C#

#20
post #18

Earlier quoted context omitted.

What you describe really sounds like functional programming.

Yes, it's probably closer to functional programming than OOP, but I feel that strict functional programming doesn't adapt well to some use-cases, and there really needs to be a modular model involved as well. I think a new mainstream language would be best to be a hybrid of some sort.

[deleted]
Post reply on HN