Je suis surpris d'apprendre qu'après 5 ans, toutes les réponses souffrent encore d'un ou plusieurs des problèmes suivants:
- Une fonction autre que celle ReadLine est utilisée, causant une perte de fonctionnalité. (Supprimer/retour arrière/haut-clé pour l'entrée précédente).
- La fonction se comporte mal quand il est invoqué à plusieurs reprises (la ponte de plusieurs threads, beaucoup de pendaison de ReadLine, ou sinon un comportement inattendu).
- Fonction s'appuie sur un week-attendre. Ce qui est horrible déchets car l'attente est prévu pour fonctionner n'importe où à partir d'un certain nombre de secondes jusqu'à l'expiration, qui peut être de plusieurs minutes. Un occupé-attendre, s'étendant sur une telle quantité de temps est horrible sucer des ressources, ce qui est particulièrement mauvais dans un multithreading scénario. Si les occupé-attendre est modifié avec un sommeil, ce qui a un effet négatif sur la réactivité, même si j'avoue que ce n'est probablement pas un énorme problème.
Je crois que ma solution va résoudre le problème d'origine, sans souffrir d'aucun des problèmes ci-dessus:
class Reader {
private static Thread inputThread;
private static AutoResetEvent getInput, gotInput;
private static string input;
static Reader() {
inputThread = new Thread(reader);
inputThread.IsBackground = true;
inputThread.Start();
getInput = new AutoResetEvent(false);
gotInput = new AutoResetEvent(false);
}
private static void reader() {
while (true) {
getInput.WaitOne();
input = Console.ReadLine();
gotInput.Set();
}
}
public static string ReadLine(int timeOutMillisecs) {
getInput.Set();
bool success = gotInput.WaitOne(timeOutMillisecs);
if (success)
return input;
else
throw new TimeoutException("User did not provide input within the timelimit.");
}
}
L'appel est, bien sûr, très facile:
try {
Console.WriteLine("Please enter your name within the next 5 seconds.");
string name = Reader.ReadLine(5000);
} catch (TimeoutException) {
Console.WriteLine("Sorry, you waited too long.");
}
Alors, comment au sujet de ces problèmes de les autres solutions que j'ai mentionné?
- Comme vous pouvez le voir, ReadLine est utilisée, évitant ainsi le premier problème.
- La fonction se comporte correctement lorsqu'il est appelé à de multiples reprises. Indépendamment de savoir si un délai d'attente se produit ou pas, un seul thread d'arrière-plan ne sera jamais en cours d'exécution et au plus un appel à l'ReadLine sera jamais actif. L'appel de la fonction se traduit toujours par la dernière entrée, ou dans un délai d'expiration, et l'utilisateur n'aura pas à frapper participer plus d'une fois à présenter son entrée.
- Et, évidemment, la fonction ne dépend pas d'un occupé-attendre. Au lieu de cela il utilise la bonne techniques de multithreading pour éviter de gaspiller des ressources.
Le seul problème que j'entrevois avec cette solution est qu'elle n'est pas thread-safe. Cependant, plusieurs threads ne pouvez pas vraiment demander à l'utilisateur pour entrer dans le même temps, de sorte que la synchronisation doit se faire avant de faire un appel à l' Reader.ReadLine
de toute façon.