Ответ 1
Да, что вы делаете.
Но обычно это нравится:
bool keepRunning = true;
...
while(keepRunning){
}
Потому что иногда вам может нравиться иметь кого-то/что-то еще, чтобы иметь возможность остановить вас.
Я относительно новичок в кодировании; большая часть моей "работы" - это просто простые графические приложения, которые работают только для одного, поэтому мне не пришлось много писать.
В любом случае, одна вещь, о которой мне интересно, - это если вы хотите сохранить поток навсегда, чтобы выполнять любую работу (обработку, ожидание ввода, что угодно), нормально ли форматировать его так:
while (true) {
// do stuff
Thread.Sleep(1000);
}
(или что-то в этом роде)...? Или это небезопасно и следует ли его избегать, если это возможно?
Да, что вы делаете.
Но обычно это нравится:
bool keepRunning = true;
...
while(keepRunning){
}
Потому что иногда вам может нравиться иметь кого-то/что-то еще, чтобы иметь возможность остановить вас.
Дополнительно Вы можете использовать System.Threading.Timer. В этом случае нам не нужно использовать метод "Сон". Простой пример:
public sealed class TimerTask
{
private Timer _timer;
private int _period;
public TimerTask(int period)
{
_period = period;
_timer = new Timer(new TimerCallback(Run), "Hello ....", Timeout.Infinite, period);
}
public void Start()
{
_timer.Change(0, _period);
}
public void Stop()
{
_timer.Change(Timeout.Infinite, Timeout.Infinite);
}
private void Run(Object param)
{
Console.WriteLine(param.ToString());
}
}
Использование:
public static class Program
{
[STAThread]
static void Main(String[] args)
{
TimerTask task = new TimerTask(1000);
Console.WriteLine("Timer start.");
task.Start();
Console.ReadLine();
Console.WriteLine("Timer stop.");
task.Stop();
Console.ReadLine();
Console.WriteLine("Timer start.");
task.Start();
Console.ReadLine();
Console.WriteLine("Timer stop.");
task.Stop();
Console.ReadLine();
}
}
Выход консоли:
Timer start.
Hello ....
Hello ....
Hello ....
Timer stop.
Timer start.
Hello ....
Hello ....
Timer stop.
Чтобы разработать немного больше, если нить спала, когда ОС идет, чтобы активировать поток, он просто проверит, будет ли он еще спать, и если да, то просто введите свой временной лимит.
Если вы оставите Сон и сделаете что-то вроде
while (true)
{
if (workAvailable)
{
doWork();
}
}
то даже если workAvailable является ложным, он будет продолжать вращаться, пока ОС не остановит его, заняв весь свой фрагмент, ничего не делая. Очевидно, что немного более неэффективно.
Вы можете стать еще более сложными по мере необходимости с помощью мьютексов, семафоров и много чего, как упоминалось выше, но с ними быстро все сложнее, поэтому вы можете использовать их для решения конкретной проблемы.
В идеале вы хотите, чтобы поток был "runnable", когда он работал, и "спящий", когда нечего делать.
Это лучше всего делать с такими объектами, как взаимные исключения (мьютексы), семафоры и переменные условия, которые предоставляют механизмы для потоков, чтобы разбудить другие потоки, когда может быть что-то для них.
Просто выполнение временного сна неэффективно, потому что короткий сон означает, что поток теряет время, просыпаясь, чтобы проверить, не работает ли это, в то время как длительный сон означает, что поток может спать, пока нужно выполнить работу. Обычно это не имеет большого значения, но если код имеет дело с большими объемами запросов или данных, все идет не так хорошо.
Базовая модель работает следующим образом: Thread A помещает объекты в очередь. Thread B удаляет объект из очереди, выполняет действие и повторяется. Если в очереди нет объектов, поток B будет спать до тех пор, пока не появится объект.
Вы также должны быть осторожны, чтобы потоки, которые обращаются к общим материалам, избегают условия гонки.
Я не могу дать никакого представления о С#, но я знаю, что С# дает вам некоторые инструменты, которые помогут вам.
Так же, как некоторая дополнительная информация, типичные конечные циклы используют
for(;;)
{
...
}
поскольку в цикле нет сравнения. При выполнении потоков лучше всего проверять флаг, если цикл заканчивается или нет, хотя.