יום שני 16 אפריל 2012 15:19
In my Silverlight application I used the BackgroundWorker and the Thread.Sleep method. The Thread.Sleep is called frequently. When porting this to a Metro app, I use the Task.Delay method.
I did some performance tests because it is called frequently, and found out that calling Task.Delay is costing some time/performace. If I call the Task.Delay 1000 times with a TimeSpan of 1 millisecond, it takes about 16 seconds. Ideally this would only take 1 second. I also tried with System.Threading.SpinWait.SpinUntil, but this also takes about 16 seconds.
The same scenario in the Silverlight application with the Thread.Sleep takes about 2 seconds.
Is there in the Metro framework an API which gives me the same performance as in .Net regarding sleep/delay functionality?
ThreadPoolTimer.CreatePeriodicTimer might be a soultion (I think), but it requires me to rewrite code. So that is not my first option.
יום שני 16 אפריל 2012 16:45
Instead of using Task.Delay one can use "new System.Threading.ManualResetEvent(false).WaitOne(milliseconds);". It performs even better than Thread.Sleep (about 1.5 seconds). Anyone knows if this approach has any disadvantages?
Just as a side-note, because I am running this on a background thread through Windows.System.Threading.ThreadPool.RunAsync, I have to check the dispatcher if I have acces to the UI thread.
- סומן כתשובה על-ידי Ronald Eekelder יום שני 16 אפריל 2012 16:45
יום שני 16 אפריל 2012 19:39It doesn't sound like performance issue, but rather timer resolution issue. Just because you ask for 1ms delay doesn't mean you will get it. If system timer "ticks" in 15ms intervals then you will get delayed by 7ms on average. 16 seconds does sound a bit high, maybe the issue is the result of invoking on ui dispatcher which would cause another delay. In your situation I would definitely would look into DispatcherTimer or some other timer type.
יום שלישי 17 אפריל 2012 10:39
If you ask a thread to pause for a total of 1 seconds (in 1000 pieces) and it takes 16 seconds, than the overhead is rather big. So performance is maybe not the right term, probably overhead is better.
The Task.Delay is called from the UI thread, but the SpinWait.SpinUntil not, and they take the same amount of time. So I don't think calling from a UI thread has a lot of impact.
Just for your info. The delays might vary from 5 milliseconds to 2 seconds, because it is a recorder/replay of events. A timer might be a good solution, as you suggested, but because of a existing code base, I don't want to refactor code if it is not nescessary.