Benjol
Benjol

Reputation: 66531

Wrapping slow synchronous I/O for asynchronous UI consumption

I have an external library which does slow I/O (serial+wireless, etc...), with no async (even old-style) in the API.

I'm trying to work out a way to wrap this for easy consumption from UI, so that my user can connect without the whole UI freezing, and preferably so I can just async-await it.

But I'm reading conflicting advice, like "only use Task.Run for CPU-bound operations".

So, what should I do? Just async-await a Task.Run (omitting ConfigurAwait(false)), or implement a whole INotifyCompletion?

Upvotes: 3

Views: 205

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 456457

It's important to distinguish from "ideal" and "real-world". Ideally, async should be all the way. Ideally, all I/O should be asynchronous and not use up thread pool threads, and Task.Run is only used for CPU-bound methods. Ideally, async void should only be used for event handlers.

In the real world, sometimes you have to mix async and sync due to lack of time (or library support). In the real world, not all I/O operations have asynchronous APIs, and even shiny-new types like HttpClient use thread pool threads to work around old DNS resolution code that no one wants to take the time to fix. In the real world, async void is sometimes a cleaner approach than bare continuations, even when it's not being used for event handlers.

In your case, I would just use Task.Run and not worry about it. The main problems with Task.Run are when you're using it in an ASP.NET app or in a library, where it can interfere with other usage of the thread pool. Since you're working on a UI application, using Task.Run for I/O isn't "ideal", but it's a perfectly fine option as a tradeoff.

Upvotes: 7

Related Questions