Comment mettre mon programme C # en veille pendant 50 millisecondes?
Cela peut sembler une question facile, mais j'ai un moment d'insuffisance cérébrale temporaire!
Comment mettre mon programme C # en veille pendant 50 millisecondes?
Cela peut sembler une question facile, mais j'ai un moment d'insuffisance cérébrale temporaire!
Réponses:
System.Threading.Thread.Sleep(50);
Rappelez-vous cependant que le faire dans le thread principal de l'interface graphique empêchera votre interface graphique de se mettre à jour (cela semblera "lent")
Supprimez simplement le ;
pour le faire fonctionner également pour VB.net.
Il y a essentiellement 3 choix pour attendre dans (presque) n'importe quel langage de programmation:
pour 1. - Attente lâche en C #:
Thread.Sleep(numberOfMilliseconds);
Cependant, le planificateur de threads Windows entraîne une précision d' Sleep()
environ 15 ms (donc Sleep peut facilement attendre 20 ms, même s'il est prévu d'attendre juste 1 ms).
pour 2. - Une attente serrée en C # est:
Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
//some other processing to do possible
if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
{
break;
}
}
Nous pourrions également utiliser DateTime.Now
ou d'autres moyens de mesure du temps, mais Stopwatch
c'est beaucoup plus rapide (et cela deviendrait vraiment visible en boucle serrée).
pour 3. - Combinaison:
Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
//some other processing to do STILL POSSIBLE
if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
{
break;
}
Thread.Sleep(1); //so processor can rest for a while
}
Ce code bloque régulièrement le thread pendant 1 ms (ou légèrement plus, selon la planification du thread du système d'exploitation), donc le processeur n'est pas occupé pendant cette période de blocage et le code ne consomme pas 100% de la puissance du processeur. D'autres traitements peuvent toujours être effectués entre les blocages (tels que: mise à jour de l'interface utilisateur, gestion des événements ou faire des choses d'interaction / communication).
Vous ne pouvez pas spécifier une heure de veille exacte dans Windows. Vous avez besoin d'un système d'exploitation en temps réel pour cela. Le mieux que vous puissiez faire est de spécifier un temps de sommeil minimum . Ensuite, c'est au planificateur de réveiller votre thread après cela. Et ne faites jamais appel .Sleep()
au thread GUI.
Depuis que vous avez une fonction asynchrone / attente, la meilleure façon de dormir pendant 50 ms est d'utiliser Task.Delay:
async void foo()
{
// something
await Task.Delay(50);
}
Ou si vous ciblez .NET 4 (avec Async CTP 3 pour VS2010 ou Microsoft.Bcl.Async), vous devez utiliser:
async void foo()
{
// something
await TaskEx.Delay(50);
}
De cette façon, vous ne bloquerez pas le thread d'interface utilisateur.
FlushAsync
version.
async
déclaration est d'appelerTask.Delay(50).Wait();
Utilisez ce code
using System.Threading;
// ...
Thread.Sleep(50);
Thread.Sleep(50);
L'exécution du thread ne sera pas planifiée par le système d'exploitation pendant la durée spécifiée. Cette méthode modifie l'état du thread pour inclure WaitSleepJoin.
Cette méthode n'effectue pas de pompage COM et SendMessage standard. Si vous devez dormir sur un thread qui a STAThreadAttribute, mais que vous souhaitez effectuer un pompage COM et SendMessage standard, envisagez d'utiliser l'une des surcharges de la méthode Join qui spécifie un intervalle de délai d'expiration.
Thread.Join
Pour plus de lisibilité:
using System.Threading;
Thread.Sleep(TimeSpan.FromMilliseconds(50));
Le meilleur des deux mondes:
using System.Runtime.InteropServices;
[DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]
private static extern uint TimeBeginPeriod(uint uMilliseconds);
[DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
private static extern uint TimeEndPeriod(uint uMilliseconds);
/**
* Extremely accurate sleep is needed here to maintain performance so system resolution time is increased
*/
private void accurateSleep(int milliseconds)
{
//Increase timer resolution from 20 miliseconds to 1 milisecond
TimeBeginPeriod(1);
Stopwatch stopwatch = new Stopwatch();//Makes use of QueryPerformanceCounter WIN32 API
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < milliseconds)
{
//So we don't burn cpu cycles
if ((milliseconds - stopwatch.ElapsedMilliseconds) > 20)
{
Thread.Sleep(5);
}
else
{
Thread.Sleep(1);
}
}
stopwatch.Stop();
//Set it back to normal.
TimeEndPeriod(1);
}