Это будет работать, если ваши команды состоят из одного символа.
Class a
{
main()
{
bool done = false;
Console.CancelKeyPress += (s, e) => { done = true; e.Cancel = true; };
while(!done)
{
f(a);
g(b);
if (Console.KeyAvailable)
{
switch(Console.ReadKey().KeyChar)
{
case 'i':
case 'I':
DoSomethingImportant();
break;
case 'E':
case 'e':
done = true;
break;
}
}
}
}
}
Если команды длиннее одного символа, вы можете сохранить ключи в буфере и искать выполненные команды при каждом нажатии клавиши.
Существуют и другие, более сложные решения, связанные с многопоточностью, но если вам не нужно идти в этом направлении, то вам не следует.
(Я добавил обработку CTRL-C в приведенном выше коде, поэтому он будет корректно завершаться, если пользователь попытается остановить программу. Эта часть является необязательной.)