Reputation: 2512
Excuse my ignorance, but I am having problems understanding the MSDN excerpt for reading file contents asynchronously
https://msdn.microsoft.com/en-us/library/jj155757.aspx
string text = await ReadTextAsync(filePath);
...
private async Task<string> ReadTextAsync(string filePath)
{
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize: 4096, useAsync: true))
{
StringBuilder sb = new StringBuilder();
byte[] buffer = new byte[0x1000];
int numRead;
while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
string text = Encoding.Unicode.GetString(buffer, 0, numRead);
sb.Append(text);
}
return sb.ToString();
}
}
How is that reading asynchronously? It appears to wait until ReadTextAsync
has completed to return the contents. If there were a Thread.Sleep
inserted inside that method, then it would wait to complete, and no further code would run, after the call to the method.
Upvotes: 0
Views: 2899
Reputation: 2512
The problem was with a lack of understanding from myself about the async modifier.
The original example is running asynchronously, but any extra slow completing code added into the method, would run synchronously and wait until the calling thread had completed. If a Sleep
was really wanted then the entire call could be wrapped in a new Task
and called, returning the task and not the result.
This does not pause program execution when you are reading from an external drive for example.
public Task<string> ReadTextAsync(string filePath)
{
var task = new Task<string>(() =>
{
Thread.Sleep(5000);
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize: 4096, useAsync: true))
{
StringBuilder sb = new StringBuilder();
byte[] buffer = new byte[0x1000];
int numRead;
while ((numRead = sourceStream.Read(buffer, 0, buffer.Length)) != 0)
{
string text = Encoding.ASCII.GetString(buffer, 0, numRead);
sb.Append(text);
}
return sb.ToString();
}
});
task.Start();
return task;
}
Upvotes: 0
Reputation: 62298
In a nut shell await
makes sure that for I/O operations (like database queries, file reads, network writes, etc) that the thread is released back to the O/S while the code waits for the result on a completion port. This way your threads or not sitting around indling waiting on I/O to complete, now they can be reused by the O/S for other activities. Once the I/O completes the O/S will reassign a new thread OR use the original thread (depending on ConfigureAwait) to resume the operation.
So this is not parallel or concurrent programming, it is simply allowing the thread to service other requests while a process (code point) waits on I/O to complete.
Also see Asynchronous Programming with Async and Await for additional details.
Upvotes: 1