-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
File.ReadAllTextAsync not behaving asynchronously when called on inaccessible network files #25314
Comments
Yeah, the problem being in the ctor would make sense. Ideally we'd have a |
I don't think that would be a good workaround, since it would still block the calling synchronization context. This matters especially in GUI apps, where it would still block the UI thread. Doing something like |
My idea about about only doing this for a UNC path isn't a good one, as mapped drives hide UNC and there can be other slow-to-access files. Is there anything better than |
Any caller of this method could do the same thing if they need to, but doing it in the implementation means it's being forced on to everyone. |
Not really, as obtaining the If there isn't a better way, maybe that's the real problem here, and this should wait on such a better way being implemented first. |
Sure there is: Task<string> task = Task.Run(() => File.ReadAllTextAsync(path)); or if you want to avoid the closure (though if you're ok reading the whole string and you're doing this because the operation is going to be blocking for a while, this allocation is a drop in the bucket): Task<string> task = Task.Factory.StartNew(state => File.ReadAllTextAsync((string)state), path,
CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap();
Right, Win32 doesn't provide any API that enables performing the open asynchronously. |
-> Future as this seems to haev a workaround. cc @pjanotti |
Just wasted >1h debugging my app only to discover this. Guys, this is a popular method, and this issue violates the most basic expectation about it. The whole point of using it is to ensure the calling thread is not blocked. |
The problem here is that none of the OSes that we support provides a way to asynchronously open a file. Reads and writes can be async, but not the opening. https://stackoverflow.com/questions/41300873/how-to-open-a-file-in-windows-asynchronously |
@adamsitnik is there any reason this can't be done by queuing a task on the default threadpool? |
You can do the same: Task.Run(() => File.ReadAllTextAsync(...)) As a general policy we don't queue synchronous portions of APIs. In the extreme it would mean wrapping the body of every async method with a Task.Run or equivalent, which is something we don't do in general as well. |
I don't see how the logic in this post applies to this case. Nobody is suggesting wrapping a synchronous |
It does what it can do with async I/O. It doesn't artificially do any async-over-sync work. The point was we generally don't do that. |
Closing as this seems to be non-actionable. |
When accessing a file on a network share that for some reason cannot be accessed (e.g. server not existent),
File.ReadAllTextAsync
appears to block, rather than running asynchronously, until the file request fails. This can be reproduced with the following console app:The result of running the above code is a regular stream of (the expected) "Error reading file" messages but they come in slowly one after the other.
When uncommenting the
await Task.Delay(1)
line, the messages all come in nearly simulataneously. I would have expected this behaviour without this line.I believe this is to do with the behaviour of the
new FileStream
object in https://github.com/dotnet/corefx/blob/release/2.0.0/src/System.IO.FileSystem/src/System/IO/File.cswhich is called before any code is awaited.
The text was updated successfully, but these errors were encountered: