我正在使用.NET Core 3.0上的Opentk编写3D渲染器。我遇到了一个问题,我的游戏将会有这些小的"微骨"停顿,从而我会得到这种非常小的干运动,大概可以持续50-100毫秒。这很烦人,每10-20秒发生一次。
我发现了三个引起他们的问题,并消除了其中两个问题。最后一个我不知道如何解决。
在调试模式下观看输出窗口后,我注意到微型流量似乎几乎总是与以下记录相吻合:
The thread 0x4f1e has exited with code 0 (0x0).
线程ID将变化。
我的目标是摆脱这些产卵的内容...但是即使在游戏机应用程序中,它们似乎也在发生,该应用程序永远循环如下
using System;
namespace ThreadStutterTestApp
{
class Program
{
static void Main(string[] args)
{
int i = 0;
while (i <= 0)
{
i = -1;
}
}
}
}
微型通信器都在调试和发布模式下发生,无论我在VS内运行应用程序是否运行(在这种情况下为VS2019(,使用.NET Core 3.0在默认C#版本上使用.NET CORE 3.0(或从其外部的命令行。
我似乎在调试或发行中获得了相同的微插图频率,因此我认为生成此线程的内容都出现在两者中。问题是我没有获得"线程...退出"。发行模式下的消息,所以我永远无法分辨出是什么原因造成的……直到今天,我才在调试模式下检查它时发生了联系。
也没有任何写入VS中输出的调用,因为当我调用Debug.WriteLine("Test");
时,在游戏中根本没有任何stutters。这似乎只链接到终止的线程。
在查看调试器中的"线程"窗口时,该线程在启动时不存在,通常会在应用程序开始后的10-15秒后出现(然后如前所述,最终将执行任何操作做然后死了,并弄乱了我的发动机性能(。
根本没有出现在.NET Core 2.0或2.1上的螺纹。但是,它确实出现在.NET Core 2.2上,但它出现一次并死了一次,仅此而已。在.NET Core 3.0上(使用C#8,但是C#版本可能与之有或可能与此有关,不太可能……但在这一点上不确定(它一直垂死并恢复。在控制台应用程序中,有一个Rogue线程,但是在Opentk中,看起来有两个线程(我认为这不是Opentk,而是出于我不了解的原因而产生第二个线程(。
我的nuget安装也为Barebones Console应用程序是空的,所以我不是一个流氓库给我为此而感到悲伤,而在基本的控制台应用程序上,这些麻烦的线程也在这样做。
。每次此神秘线程退出时,我的应用程序都会在线程退出时获得100%确保正好发生的口吃。它是完全可重复的。
我该如何解决这个问题?什么是在这个线程产卵?我可以停止吗?这是我应该报告的错误(如果是这样,在哪里(?
编辑:有趣的是,应用程序的开头似乎有〜2个与线程不一致的说,但是在这两个之后,它将始终与垂死的线程一致,。例如:
00 sec-申请开始
05 sec-微型插座,没有写入Debug窗口的线程
20秒 - 微型插座,没有写入Debug窗口的线程
40秒 - 微型插座,螺纹退出
65秒 - 微骨,螺纹退出
83秒-Microstutter,线程退出
99秒-Microstutter,线程退出
...继续,所有微座位都与螺纹退出
对齐
我能够由于有两个显示器而实时查看全屏窗口和调试。
我也一直遇到过这个游戏,这是我从事单体工作的游戏;我有相同的"神秘线程退出"。这似乎是由于什么都没有可预测的,这会导致游戏玩法"流行"。和"口吃"每隔几秒钟。有时它会受到输入的影响,有时会自行发生,但总是与"神秘线程退出"配对。我正在拔出头发,我正在考虑像切换游戏框架一样剧烈的事情,甚至将所有代码从C#移植到C 。
但是,经过大量的研究,在JIT分级编译系统中使用的.NET Core 2.2/3.x的性能计数逻辑中似乎是一个错误。背景线程似乎是JIT启动以进行先前命令的代码并进一步优化它,因为它像大量使用一样被检测到。.NET团队表示,这将在.NET 5中固定;但是目前,似乎他们建议完全关闭分层的汇编,您可以在.csproj
文件中执行此操作:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TieredCompilation>false</TieredCompilation>
</PropertyGroup>
</Project>
当然,偏低的一面是JIT的能力较低,并且可能生成较少优化的代码。但就我而言,它摆脱了意外的游戏玩法。