【发布时间】:2020-01-31 09:36:23
【问题描述】:
我已经对此进行了一段时间的研究,但多年来情况似乎发生了变化,并且有一些相互矛盾的答案。
我的传统做法是,在我的OnStart 方法中,
new Thread(new ThreadStart(QueueProcessorDoWork));
这样它会启动线程然后立即返回。
然后:
private void QueueProcessorDoWork()
{
while (_isRunning)
{
DoStuff();
Thread.Sleep(100);
}
}
没有办法让 DoStuff() 成为阻塞操作,它基本上必须轮询。
现在,Thread.Sleep 被认为是不好的做法,因为它会锁定线程。
所以研究表明我可以使用计时器。没问题,我会创建一个计时器,并将其设置为每 100 毫秒轮询一次,然后在计时器处理程序中,我将禁用计时器,进行处理,再次重新启用计时器,一切都会好起来的。
不过,我随后阅读了有关将 async/await 与 Task.Delay(100) 一起使用的信息。
听起来不错。我相信我仍然需要创建一个Thread,因为否则 OnStart 方法将不会返回。但是这还不清楚,如果我不等待就调用异步方法,我不知道会发生什么。
所以问题 1 是 - 我应该只调用一个包含无限循环的异步任务而不等待它启动我的 Windows 服务吗?
如果我确实想在线程中使用 async/await,我该如何开始?我的 ThreadStart 可以调用一个函数,而该函数又会执行 Task.Run(async () => Worker()) 或其他什么,我不确定,因为调用者需要被标记为异步?
所以问题 2 是,我将如何在对 new Thread() 的调用中设置异步/等待模式?
最后一个问题是,这两种方法中的哪一种(或两者兼有?)是启动无限处理循环的“正确”方法?
【问题讨论】:
-
坚持使用计时器。
-
OnStart方法必须在设置处理循环后立即返回,因为它是 Windows 服务。与许多示例一样,副本创建计时器,然后以无限循环的形式坐在那里。但就我而言,我必须立即从 OnStart 返回。我猜定时器的设置应该在一个新线程上。我不确定 async/await 是否应该参与其中。 -
您可以触发并忘记一个任务,就像您可以触发并忘记一个线程一样。 Task.Run() 将在另一个线程上运行,一个来自默认工作池。然后您可以使用 Thread.Sleep() 等。但是如果您只有一个线程并且您必须睡觉(或
Task.Delay())并且您不希望它在该线程中一次做多件事,那么我可以'从任务中看不到任何好处。
标签: c# multithreading async-await windows-services