-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Console issues with multithreaded c# app only when run on Linux #49301
Comments
Not your actual problem, but can cause issues nonetheless;
|
The behavior you see is because fetching the cursor position ( runtime/src/libraries/System.Console/src/System/ConsolePal.Unix.cs Lines 470 to 475 in ec18977
|
@tmds as this behaviour is different to windows, will this be considered a bug or be a caveat that I need to work around? @Clockwork-Muse I would rather manage my threads directly as they are long running network listeners, I do not want to pass them to a thread pool in a fire and forget manor. Thanks to both of you for your comments :) |
It's a documented (at least in code) limitation of the implementation. In your case, instead of |
Thanks @tmds the use of |
I wonder whether it would help if Console had an event for input as an alternative to Read()/ReadLine(). Similar to Process.OutputDataReceived |
…-log-entries` config on dotnet It required user input to release lock before collapsed repeated log was printed. The behavior is because fetching the cursor position (Console.CursorTop getter) and Console.Read* take the same lock: dotnet/runtime#49301 (comment). Renode running with `--console` switch interleaves log output and monitor input in a single shell. The proposed solution is a workaround that ignores `collapse-repeated-log-entries` config on dotnet and prints all lines.
…-log-entries` config on dotnet It required user input to release lock before collapsed repeated log was printed. The behavior is because fetching the cursor position (Console.CursorTop getter) and Console.Read* take the same lock: dotnet/runtime#49301 (comment). Renode running with `--console` switch interleaves log output and monitor input in a single shell. The proposed solution is a workaround that ignores `collapse-repeated-log-entries` config on dotnet and prints all lines.
This behavior difference was surprising to me. My temporary workaround: private static async Task<ConsoleKeyInfo> ReadKeyInternalAsync(bool intercept)
{
// the deadlock issue is only on linux
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return Console.ReadKey(intercept);
}
// asynchronously wait for a key press to become available
while (!Console.KeyAvailable)
{
await Task.Delay(50).ConfigureAwait(false);
}
return Console.ReadKey(intercept);
} |
Based on what @tmds wrote in #49301 (comment) I don't see us fixing it in the near future. |
Description
Standard design for a c# console application is for the main thread to start worker threads, in my case listening for network connections, and then enter a while loop blocking on Console.Readline waiting for any console input. The documentation supports this model as console should support multithreading and when running on windows it does as expected. When running on linux with dotnet 3.1 runtimes it does not. When the main thread blocks on Readline as expected, any calls to Write to console also block and freeze that thread until a console command is issues releasing the readline block then those frozen writes to console are triggered. I am sure this is a bug as the code works as expected in windows as documented. It is only in linux environment that this console blocking behaviour is displayed. I have also noticed in my server code, under linux the startup gets some data from Console.Readline the first call that is not typed in the screen. It is displayed as squares indicating it is byte data that can not be interpreted as a string.
I have included a small sample code that shows the first thread blocking behaviour but does not show the garbage that console readline picks up, this would require more testing and isolation of the cause with my full server solution.
Summary is that when Console.Readline blocks main thread, other worker threads should be able to write to console and not block themselves causing application to freeze. Again important part of this is that it works on windows but not linux.
Configuration
Regression?
Unknown
Other information
Example Code:
The text was updated successfully, but these errors were encountered: