Skip to content
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

A question about PipeOptions.Asynchronous and async/await #24567

Closed
iam3yal opened this issue Jan 4, 2018 · 5 comments
Closed

A question about PipeOptions.Asynchronous and async/await #24567

iam3yal opened this issue Jan 4, 2018 · 5 comments
Milestone

Comments

@iam3yal
Copy link

iam3yal commented Jan 4, 2018

I'm not sure but it seems like PipeOptions.Asynchronous should only be used with the old async APIs Begin* and End* pair, is this correct? because from my tests using an example I wrote for an issue I had at SO (at the bottom of the page) it hangs if it isn't set to PipeOptions.None this surprised me because behind the scenes it seems like it takes advantage over the old APIs but otherwise it certainly possible that I'm doing something wrong.

Tested with .NET 4.7.1 and Core 2.0.

@iam3yal
Copy link
Author

iam3yal commented Jan 4, 2018

This seems to be the case for FileStream too not just pipes so I guess it relates to any kind of stream.

@stephentoub
Copy link
Member

No, that's not the case. It should work fine with the task-based method. Please share the standalone repro in the issue.

@iam3yal
Copy link
Author

iam3yal commented Jan 4, 2018

@stephentoub There you go PipesAsyncAwait471.zip

p.s. I ran the exact same code on Core 2.

@stephentoub
Copy link
Member

PipeOptions.Asynchronous is simply causing a different order of execution than PipeOptions.None, and that's exposing a race condition / deadlock in your code. You can see the effect of it if you use Task Manager, for example, to monitor the thread count of your process... you should see it creeping up at a rate of appx 1 thread per second, until it gets to around 100 threads (maybe 110 or so), at which point your code runs to completion. Or if you add ThreadPool.SetMinThreads(200, 200) at the beginning. Your code has a problem where if the wrong ordering occurs (and that's made more likely by using Asynchronous), you create a cycle where it can't be satisfied until there are enough threads to run all of the concurrent ConnectAsyncs your main method has queued, which aren't truly async and instead just create a work item to invoke the synchronous Connect method (this is unfortunate, and it's issues like this that are one of the reasons I urge folks not to expose async APIs that simply queue works items to call sync methods).

@iam3yal
Copy link
Author

iam3yal commented Jan 4, 2018

@stephentoub Okay thanks, I'll look into it.

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 2.1.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants