2

I'm trying to understand async and await, and I've got a few questions. In this example from Microsoft

async Task<int> AccessTheWebAsync()
{ 
    // You need to add a reference to System.Net.Http to declare client.
    HttpClient client = new HttpClient();

    // GetStringAsync returns a Task<string>. That means that when you await the 
    // task you'll get a string (urlContents).
    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

    // You can do work here that doesn't rely on the string from GetStringAsync.
    DoIndependentWork();

    // The await operator suspends AccessTheWebAsync. 
    //  - AccessTheWebAsync can't continue until getStringTask is complete. 
    //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
    //  - Control resumes here when getStringTask is complete.  
    //  - The await operator then retrieves the string result from getStringTask. 
    string urlContents = await getStringTask;

    // The return statement specifies an integer result. 
    // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
    return urlContents.Length;
}
  1. The method uses client.GetStringAsync, however, what happens if the method you're calling isn't an Async method? If I were calling for example, File.ReadAllLines(), how would I make that an Async call?

  2. The method has a return type of Task<int>. Does any method that uses await, have to have a return type of Task<>? What if there is nothing to return?

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • 2. Then you write `async Task AccessTheWebAsync()` – Toumash Jun 29 '15 at 00:09
  • A fairly Broad question so here are some nice broad [examples](http://www.dotnetperls.com/async), [how and when to use](http://stackoverflow.com/questions/14455293/how-to-and-when-use-async-and-await/19985988#19985988), [why do we need them](http://blogs.msdn.com/b/cdndevs/archive/2013/12/19/10483217.aspx) – lloyd Jun 29 '15 at 00:10
  • if there is nothing to return then you will just write await Task(...); – M.kazem Akhgary Jun 29 '15 at 00:10
  • 1 is covered in http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx (basically "don't do that"). 2 should not be asked in the same question, but is answered by the article you've linked (and additional info referenced from it - [Async return Types](https://msdn.microsoft.com/en-us/library/hh524395.aspx) ). If it would not be summer you'd receive downvotes for asking multiple questions or not reading article you've linked. – Alexei Levenkov Jun 29 '15 at 01:28

3 Answers3

1

The method uses client.GetStringAsync, however, what happens if the method you're calling isn't an Async method? If I were calling for example, File.ReadAllLines(), how would I make that an Async call?

Don't drive async from the "outside in"; rather, let it bubble up from the "inside out". In other words, if you want to make something asynchronous, you first find the lowest-level APIs that are asynchronous, then you make the calling method async.

The method has a return type of Task. Does any method that uses await, have to have a return type of Task<>? What if there is nothing to return?

Then the result type of the method should be Task.

Technically, async methods can return Task, Task<T>, or void. You should avoid async void; it should only be used for event handlers (or methods that are logically event handlers). Task<T> is a wrapper around a result type of T; this wrapper also includes information about any exceptions. Similarly, Task contains valuable information about exceptions (or successful completion).

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
0
  1. You would call the appropriate Async method. If there isn't one, then it won't be truly asynchronous. You could "make" your own by wrapping it with Task.Run() but it really defeats the purpose of being async. This is fine in a desktop app, but it's a terrible idea to do in an ASP.NET/server scenario because you're creating more threads to handle the same functionality. (Too many threads means your throughput will suffer in server scenarios). All I/O (database ,file access) in .NET should have the appropriate Async() methods along with the standard blocking methods. For a deeper discussion on why this is a bad idea, see Stephen Taub's blog post on it.

  2. Any method using the async/await pattern has to return a Task<>. This is because while the system is "await'ing", it will return a Task<>, which represents a future promise of the return type. The calling method can continue on if it wishes to other code, or it can stay await'ing your async method call and provide scalability benefits until the true underlying type has been returned from that async method.

Tim P.
  • 2,903
  • 24
  • 26
  • 1
    To expand on this, an equivalent async method for `File.ReadAllLines()` is [`StreamReader.ReadToEndAsync()`](https://msdn.microsoft.com/en-us/library/system.io.streamreader.readtoendasync(v=vs.110).aspx) –  Jun 29 '15 at 01:47
0

If I were calling for example, File.ReadAllLines(), how would I make that an Async call?

You don't "make something" async, it has to be naturally so. Many operations are IO bound, such as a network call or accessing disk. There is no File.ReadAllLinesAsync, but you can write one yourself using a "lower-level" API such as FileStream.

Does any method that uses await, have to have a return type of Task<>? What if there is nothing to return?

No, it doesn't. A Task<T> is used when you have a return value from an asynchronous method. In your example, that value is a string. It is wrapped in a Task<> because a Task is a promise of work which will complete in the future. Awaiting on a Task<string> asynchronously waits until the async operation is done and that string is returned.

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321