XNA with TaskFactory execution times when executing SetData on Texture in a loop

268 Views Asked by At

Though this question is about an implementation in XNA, i think it is a better fit for a more general C# forum. I am using the TaskFactory with XNA to initialize additional resources while presenting a loading screen to the user. The code is similar to this:

        Task.Factory.StartNew(() => DoSomeInitialStuff()) 
          .ContinueWith((x) => BuildALevel(x.Result)) 
          .ContinueWith((x) => DoSomeFinalizingStuff(x.Result)) 
          .ContinueWith((x) => NotifyThatIAmFinished()); 

I have logged the times needed, and my DoSomeFinalizingStuff method will take longer when my main window is in focus. DoSomeFinalizingStuff actually writes to a 400x400 Texture2D (which is not displayed in the process, just created and modified) using the SetData method.

AVG Time taken when in focus and visible: ~5000ms (up to 10k+ at times) AVG Time taken when not in focus (and not visible): ~100ms

The time measured is actual execution time of DoSomeFinalizingStuff. Thats at AVG a factor of 50 difference, i am pretty curios, why that is the case.

When running the debugger both all chained tasks together need about a second to complete. When run without debugging and no interaction it is a lot slower, usually the loading screen sits there for about 10-15 seconds until its complete.

I can "trigger" the Task to execute faster when i switch focus away from my main window. As soon as i switch away, the function gets executed.

If i remove the SetData() calls, performance is the same as when debugging or windows i inactive.

Why is this happening and is there a way to modify this behavior?

1

There are 1 best solutions below

4
On

Looks like you have a synchronization issue.

One possible cause is that ContinueWith inherits TaskScheduler (if you run it from a task with scheduler initialized with TaskScheduler.FromCurrentSynchronizationContext() it will have it too). Try calling you ContinueWith this way: ContinueWith(...,TaskScheduler.Default).

If it's not the case, then try looking at 'Parallel Tasks' and other thread-related windows during debugging. It might help you identify the problem.