хотелось мне для синхронного console.readkey()
ограничить время его действияАвтор: PhantomIvan
Дата: 23.09.06
чтобы юзер, легший спать, не просыпался каждые 5 минут нажать кнопку
для этого я написал макрос
public macro limit_time (expression, time, default)
{
def invoke =
<[ {
mutable result;
def thread = Thread(() => result = $expression);
thread.Start();
if (thread.Join($time))
result
else
{
thread.Abort();
//thread.Join();
$default
}
} ]>;
<[ $invoke ]>
}
на самом деле, для консоли мне там подсказали более правильный вариант
но вдруг кому макрос понадобится
у этого способа есть недостатки: обратите внимание на
//thread.Join();
у меня с моим вызовом по типу
def pressed = limit_time (ReadKey(), AutoInterval, ConsoleKeyInfo(Auto, ConsoleKey.A, false, false, false));
плодятся треды в количестве 1 штука на вызов, и я понял почему
thread.Abort() вызывает исключение в треде, и его можно даже обработать
но рантайм пошлет это исключение только после того, как управление вернется из unmanaged-блока, если оно в нем находится
а в console.readkey() по сути вызов к функции winapi, поэтому тред терпеливо ждет нажатия клавиши, и не закрывается даже после аборта
thread.Join, если его раскомментировать, обязательно дождется разрушения потока, но макрос limit_time() (иногда) работать не будет, т.к. когда поток соизволит закрыться — это не определено, и макрос может вместо ограничения времени подвесить программу (что в моем случае и происходило)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
30.01.07 18:13: Перенесено модератором из 'Декларативное программирование' — IT