在我的许多项目中,我发现自己正在这样做:
var thread = new Thread(MyFunc);
thread.Start()
...
MyFunc()
{
while (true)
{
; Do something
Thread.Sleep(10);
}
}
一个用例示例是轮询DirectInput API以获取操纵杆输入。
这是基于轮询的API,而不是基于事件的API。
我最近一直在研究如何使用最新的机制来达到相同的结果-我得到的建议是,任务是处理异步代码的现代方法。
因此,我对SO进行了一些挖掘,并找到了一些基本上可以做到这一点的代码:
_period = 10;
_cancellationTokenSource = new CancellationTokenSource();
while (!_cancellationTokenSource.Token.IsCancellationRequested)
{
await Task.Delay(_period, _cancellationTokenSource.Token);
if (!_cancellationTokenSource.Token.IsCancellationRequested)
_action();
}
但是,似乎要使用更多的CPU。
我有一个测试项目here,试图比较这两种技术和相关的CPU开销,看来基于任务的方法使用的CPU数量是原来的两倍。
不过,这是我第一次使用VS perf测试工具,因此我可能会严重误解结果。
正如我在回购自述文件中提到的那样,CPU命中率对我很重要-这用于重新映射在系统处于高负载(玩游戏)时运行的应用程序。我愿意牺牲一些性能来获得更好的代码,但不会使CPU命中率翻倍。
回购中还有一些代码用于“超时”类型的计时器(设计为非常快速地重置),对此的任何输入也将不胜感激。