Dostaję dziwny problem podczas korzystania z Console.ReadKey()
w programie wielowątkowym.Dziwne zachowanie Console.ReadKey() z wielowątkowością
Moje pytanie brzmi: dlaczego tak się dzieje? Czy to błąd, czy też dlatego, że nadużywam Console
? (Zauważ, że konsola jest powinien być threadsafe, according to the documentation.)
Najłatwiej wyjaśnić to z kodem:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("X"); // Also try with this line commented out.
Task.Factory.StartNew(test);
Console.ReadKey();
}
private static void test()
{
Console.WriteLine("Entering the test() function.");
Thread.Sleep(1000);
Console.WriteLine("Exiting the test() function.");
}
}
}
Co sądzisz że będzie wydrukować po uruchomieniu go i don 't naciśnij klawisz?
Odpowiedź jest po prostu to, czego można się spodziewać:
X
Entering the test() function.
Exiting the test() function.
Teraz zakomentuj Console.WriteLine("X")
i uruchomić go ponownie (bez naciskania klawisza). Spodziewałem się zobaczyć tego wyjścia:
Entering the test() function.
Exiting the test() function.
Zamiast tego widzę nic. Po naciśnięciu klawisza:
Entering the test() function.
... i to wszystko. Program wychodzi (oczywiście) i nie ma czasu, aby przejść do następnego WriteLine()
.
Uważam to zachowanie za bardzo tajemnicze. Łatwo się obejść, ale jestem zaintrygowany, dlaczego tak się dzieje.
[EDIT]
jeśli dodać Thread.Sleep(1)
bezpośrednio przed Console.ReadKey()
to działa zgodnie z oczekiwaniami. Oczywiście nie powinno to być konieczne, ponieważ i tak należy czekać na zawsze.
Wygląda na to, że może to być jakiś rodzaj wyścigu?
Więcej informacji: Servy znalazła (i mam powielone), że linia Console.WriteLine("Entering the test() function.")
blokuje się, dopóki nie zostanie naciśnięty żaden klawisz.
Konfiguracja Budowa
Visual Studio 2012, Windows 7 x64, Quad Core, Angielski (UK).
Próbowałem wszystkich kombinacji .Net4, .Net4.5, x86, AnyCPU oraz debugowania i wydawania, i żaden z nich nie działa na moim komputerze. Ale stało się coś naprawdę dziwnego. Zaczęło działać, gdy po raz pierwszy wypróbowałem wersję AnyCPU dla .Net4, ale potem przestało działać. Wydaje się bardzo podobny do stanu wyścigu, który wpływa tylko na niektóre systemy.
Na podstawie moich doświadczeń jest jakaś inicjalizacji, który odbywa się po raz pierwszy konsola jest napisane, że ustawia się ramy do równoczesnego odczytuje i zapisuje. Jeśli konsola została napisana w ogóle przed pierwszym wywołaniem 'ReadKey', wszystko będzie dobrze, ale nigdy nie było napisane, aby to zachowanie było widoczne. Jak powiedziałeś, łatwe do obejrzenia, ale bardzo ciekawe. – Servy
Co się stanie, gdy wyraźnie wymusisz na konsoli. Czy chcesz spłukać? – Krypes
@Krypes Blok "Console.WriteLine" blokuje (w oparciu o moje eksperymenty), a nie kontynuuje i nic nie robi, więc nie ma możliwości opróżnienia go. – Servy