Я создал приложение для секундомера. В его конструкторе я запустил новый поток, в котором есть цикл while(true) для проверки нажатий на клавиатуру - при нажатии Space секундомер остановится; при попадании в A секундомер возобновляет работу. Это работает один раз для каждого, однако после этого он не регистрируется, и кажется, что цикл больше не работает или что-то в этом роде, потому что я помещаю журнал внутри цикла while (но вне операторов if), и он не печатается каждый цикл как я и предполагал. (Обратите внимание, что мне пришлось включить hasPressedSpace и hasPressedA booleans, потому что события ввода регистрировались несколько раз во время одного нажатия клавиши).
namespace StopWatch
{
class Program
{
static void Main(string[] args)
{
StopWatch stopWatch = new StopWatch();
stopWatch.Start();
}
}
public class StopWatch
{
public TimeSpan Duration { get; private set; }
private bool _hasStoppped;
private ThreadStart threadStart;
private Thread thread;
private bool isPaused;
public StopWatch()
{
Duration = new TimeSpan();
threadStart = new ThreadStart(KeyBoardThread);
thread = new Thread(threadStart);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
public void Start()
{
while (!_hasStoppped)
{
Thread.Sleep(100);
Duration += TimeSpan.FromMilliseconds(100);
Console.WriteLine("Duration: " + Duration);
}
}
void KeyBoardThread()
{
bool hasPressedSpace = false;
bool hasPressedA = false;
while (true)
{
if (Keyboard.IsKeyDown(Key.Space) && !hasPressedSpace)
{
hasPressedSpace = true;
hasPressedA = false;
Stop();
}
if (Keyboard.IsKeyDown(Key.A) && !hasPressedA)
{
hasPressedSpace = false;
hasPressedA = true;
_hasStoppped = false;
Start();
}
}
}
void Stop()
{
Console.WriteLine("stop called");
_hasStoppped = true;
}
}
}





Добавьте следующую строку в конец вашей основной функции:
Console.WriteLine("Exit");
Вы увидите, что после нажатия клавиши Space программа печатает «Выход». Тогда это, ну, выход!
Проблема здесь:
while (!_hasStoppped)
{
Thread.Sleep(100);
Duration += TimeSpan.FromMilliseconds(100);
Console.WriteLine("Duration: " + Duration);
}
Если _hasStoppped - это true, поток завершается, и ваша программа тоже. Вам нужно переосмыслить свою логику.
Вы также можете отметить, что Stopwatch класс встроен в .NET Framework :)
Привет, спасибо, я добавил цикл while (true) вокруг исходного цикла while, и он работает. Однако до сих пор не понимаю, как это не работало раньше. Если основной поток завершается, когда _hasstoppped = true, то как он может перезапуститься при нажатии «A», а затем он больше не принимает никаких входных данных?
@AdamJ Рад услышать, что мой ответ помог. Вы можете принять ответ, щелкнув галочку / галочку слева от него, прямо под стрелками вверх / вниз. Чтобы ответить на следующий вопрос: когда вы нажимаете пробел, вы вызываете Stop(), который устанавливает _hasStoppped = true. Когда вы нажимаете A, вы устанавливаете _hasStoppped = false. Не уверен насчет второго пункта - я бы рекомендовал использовать .NET StopWatch и подписываться на ключевые события вместо вашего текущего подхода.
Есть ли конкретная причина, по которой вы использовали опрос, а не подход, управляемый событиями?