как я могу использовать временную задержку в цикле после определенного поворота? Пусть:
for(int i = 0 ; i<64;i++)
{
........
}
Мне нужно 1 с задержка после каждого 8 вращений.
как я могу использовать временную задержку в цикле после определенного поворота? Пусть:
for(int i = 0 ; i<64;i++)
{
........
}
Мне нужно 1 с задержка после каждого 8 вращений.
Существует много способов сделать это:
Первый метод: преступный ужас: ожидание:
DateTime timeToStartUpAgain = whatever;
while(DateTime.Now < timeToStartUpAgain) {}
Это ужасная вещь; операционная система предположит, что вы делаете полезную работу и назначаете процессор, чтобы ничего не делать, кроме как откручивать его. Никогда не делайте этого, если не знаете, что вращение будет только на несколько микросекунд. В основном, когда вы делаете это, вы наняли кого-нибудь, чтобы посмотреть часы для вас; что неэкономично.
Спящий поток также ужасен, но он менее ужасен, чем нагрев процессора. Спящий поток сообщает операционной системе "этот поток этого приложения должен перестать отвечать на события на какое-то время и ничего не делать". Это лучше, чем нанять кого-то, чтобы посмотреть часы для вас; теперь вы наняли кого-то, чтобы спать для вас.
Это эффективно использует ресурсы; теперь вы нанимаете кого-то, чтобы готовить яйца, и пока яйца готовят, они могут делать тосты.
Однако больно писать вашу программу, чтобы она разбивала работу на небольшие задачи.
С другой стороны, С# 5 - это только бета-версия.
ПРИМЕЧАНИЕ. С Visual Studio 2012 С# 5 используется. Если вы используете VS 2012 или более позднее, для вас доступно асинхронное программирование.
Если вы хотите спать после каждых 8 итераций, попробуйте следующее:
for (int i = 0; i < 64; i++)
{
//...
if (i % 8 == 7)
Thread.Sleep(1000); //ms
}
Используйте Thread.Sleep (из System.Threading):
for(int i = 0 ; i<64;i++)
{
if(i % 8 == 0)
Thread.Sleep(1000);
}
Вы также можете просто посмотреть на использование Timer
, а не на приостановку текущего потока в цикле.
Это позволит вам выполнить некоторый блок кода (многократно или не) после некоторого промежутка времени. Без лишнего контекста было бы трудно сказать, насколько это лучше в вашей ситуации или как вы собираетесь изменить свое решение соответственно.
Вот реализация, с которой я столкнулся. Он общий, поэтому вы можете легко его повторно использовать для своего случая использования. (он согласуется с тем, что предложил @Servy)
public static async Task ForEachWithDelay<T>(this ICollection<T> items, Func<T, Task> action, double interval)
{
using (var timer = new System.Timers.Timer(interval))
{
var task = new Task(() => { });
int remaining = items.Count;
var queue = new ConcurrentQueue<T>(items);
timer.Elapsed += async (sender, args) =>
{
T item;
if (queue.TryDequeue(out item))
{
try
{
await action(item);
}
finally
{
// Complete task.
remaining -= 1;
if (remaining == 0)
{
// No more items to process. Complete task.
task.Start();
}
}
}
};
timer.Start();
await task;
}
}
И затем используйте его так:
var numbers = Enumerable.Range(1, 10).ToList();
var interval = 1000; // 1000 ms delay
numbers.ForEachWithDelay(i => Task.Run(() => Console.WriteLine(i + " @ " + DateTime.Now)), interval);
который печатает это:
1 @ 2/2/2016 9:45:37 AM
2 @ 2/2/2016 9:45:38 AM
3 @ 2/2/2016 9:45:39 AM
4 @ 2/2/2016 9:45:40 AM
5 @ 2/2/2016 9:45:41 AM
6 @ 2/2/2016 9:45:42 AM
7 @ 2/2/2016 9:45:43 AM
8 @ 2/2/2016 9:45:44 AM
9 @ 2/2/2016 9:45:45 AM
10 @ 2/2/2016 9:45:46 AM
Попробуйте эту более простую версию без зависимости от async или ожидания или TPL.
Код здесь
foreach (var item in collection)
{
if (cnt < 50)
{
cnt++;
DoWork(item);
}
else
{
bool stayinLoop = true;
while (stayinLoop)
{
Thread.Sleep(20000);
if (cnt < 30)
{
stayinLoop = false;
DoWork(item);
}
}
}
}
Работайте в отдельном потоке, чтобы сон не блокировал вас, мог быть фоновым работником, Begin, End методом webrequest или, возможно, асинхронной задачей или Task.Run()
function DoWork()
//Do work in a sep thread.
cnt--;
)