I'm a substantial way through developing a sizeable WPF application that will control a sophisticated piece of hardware via serial comms. At the very bottom of the application "stack" I have a serial comms tier (utilising the .Net 'SerialPort' class). Reading and writing to the h/w device is a fundamental part of the system, utilised by many different areas of the business logic tier, often interspersed with complex scientific calculations and other such logic; these BLL methods are in turn called from all over the UI tier.
Currently, everything in the business logic tier, including the SerialPort reading and writing, is synchronous. The only time I use async/await is in the UI tier, typically when calling into the business logic. Here I'll wrap the call in Task.Run()
, e.g.:-
private async void SomeButtonClick(object sender, EventArgs e)
{
await Task.Run(() => _someBLLService.TurnPumpOn());
}
This is a simple example that takes a matter of milliseconds. A more complex example would be starting a long-running process (again using the above technique); this business logic "service" will run for some seconds or minutes, collecting data from the hardware and performing other "control" functions during this time. Periodically it will broadcast data back to the UI for plotting on a chart (via a pubsub event aggregator framework). The above technique works well, allowing the UI to remain responsive while such business tier processes are taking place.
I've recently been considering going "async all the way", starting with the serial comms code (e.g. using .ReadAsync
), but this would have repercussions across the system. Dozens (if not hundreds) of business logic methods would need to be refactored into async methods, right up to the UI tier. Here I would be able to simplify the above code slightly:
private async void SomeButtonClick(object sender, EventArgs e)
{
await _someBLLService.TurnPumpOn();
}
While I'm not averse to tackling large refactoring jobs, I'm wondering what the benefits really are. A lot of folks (like Stephen Cleary) advocate the "async all the way" solution, but the main goal appears to be to keep the UI responsive when calling a long-running BLL process, which my Task.Run()
technique already does.
C# Language Async-Await Async/await will only improve performance if it allows the machine to do additional work.
If a method has no async operations inside it there's no benefit in making it async . You should only have async methods where you have an async operation (I/O, DB, etc.). If your application has a lot of these I/O methods and they spread throughout your code base, that's not a bad thing.
Asynchronous loops are necessary when there is a large number of iterations involved or when the operations within the loop are complex. But for simple tasks like iterating through a small array, there is no reason to overcomplicate things by using a complex recursive function.
Calling an asynchronous controller action will not block a thread in the thread pool. Asynchronous actions are best when your method is I/O, network-bound, or long-running and parallelizable. Another benefit of an asynchronous action is that it can be more easily canceled by the user than a synchronous request.
Since your app (presumably) is not under high load and is a GUI app the only reason to use async and await are productivity gains. Throughput and scalability do not enter the picture.
Therefore, do what is most convenient to you. This can very well be the await Task.Run
pattern that you used in the sample code.
but this would have repercussions across the system
Yes. Async has a noticeable productivity cost and it is infectious. Only do that if you can clearly articulate the benefits you reap from that choice. Here, the only benefit would be that your UI code is a few characters shorter. It's the difference between your two code snippets. The entire rest of the system gets worse.
Maybe you have been following the C# community and picked up the trend to go async all the way. Programmers are very prone to jump to magic solutions without understanding them. Many advocates of async cannot even articulate the concrete benefits they derive from it. There is a lot of group think as well. Do not base your decision on internet advice alone. Factor that in and check for yourself what makes sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With