虽然这个问题是关于XNA中的实现,但我认为它更适合更通用的C#论坛。我正在使用带有 XNA 的任务工厂来初始化其他资源,同时向用户显示加载屏幕。代码类似于以下内容:
Task.Factory.StartNew(() => DoSomeInitialStuff())
.ContinueWith((x) => BuildALevel(x.Result))
.ContinueWith((x) => DoSomeFinalizingStuff(x.Result))
.ContinueWith((x) => NotifyThatIAmFinished());
我已经记录了所需的时间,当我的主窗口处于焦点时,我的DoSomeFinalizingStuff
方法将需要更长的时间。 DoSomeFinalizingStuff
实际上使用 SetData 方法写入 400x400 Texture2D(在此过程中未显示,只是创建和修改(。
对焦和可见时的平均时间:~5000ms(有时高达10k+(未对焦(且不可见(时的平均时间:~100ms
测量的时间是DoSomeFinalizingStuff
的实际执行时间。这是AVG的50倍差异,我很好奇,为什么会这样。
运行调试器时,所有链接在一起的任务大约需要一秒钟才能完成。在没有调试和交互的情况下运行时,速度要慢得多,通常加载屏幕会在那里停留大约 10-15 秒,直到完成。
当我将焦点从主窗口移开时,我可以"触发"任务以更快地执行。一旦我切换离开,该函数就会被执行。
如果我删除 SetData(( 调用,性能与调试或窗口 i 处于非活动状态时相同。
为什么会发生这种情况,有没有办法修改这种行为?
看起来您遇到了同步问题。
一个可能的原因是ContinueWith
继承了TaskScheduler
(如果您从使用TaskScheduler.FromCurrentSynchronizationContext()
初始化的计划程序的任务运行它,它也将具有它(。试着这样称呼你ContinueWith
:ContinueWith(...,TaskScheduler.Default)
。
如果不是这种情况,请尝试在调试期间查看"并行任务"和其他与线程相关的窗口。它可能会帮助您确定问题。