【发布时间】:2018-08-01 21:25:07
【问题描述】:
我编写了一个类,该类具有在线程池中作为长时间运行的任务运行的方法。该方法是一种监视服务,用于定期发出 REST 请求以检查另一个系统的状态。这只是一个带有 try()catch() 的 while() 循环,以便它可以处理自己的异常,并在发生意外情况时优雅地继续。
这是一个例子:
public void LaunchMonitorThread()
{
Task.Run(() =>
{
while (true)
{
try
{
//Check system status
Thread.Sleep(5000);
}
catch (Exception e)
{
Console.WriteLine("An error occurred. Resuming on next loop...");
}
}
});
}
它工作正常,但我想知道是否有另一种模式可以让 Monitor 方法作为标准 Async/Await 应用程序的常规部分运行,而不是使用 Task.Run() 启动它——基本上我试图避免即发即弃的模式。
所以我尝试将代码重构为:
public async Task LaunchMonitorThread()
{
while (true)
{
try
{
//Check system status
//Use task.delay instead of thread.sleep:
await Task.Delay(5000);
}
catch (Exception e)
{
Console.WriteLine("An error occurred. Resuming on next loop...");
}
}
}
但是当我尝试在另一个异步方法中调用该方法时,我收到了有趣的编译器警告:
“由于不等待此调用,因此在调用完成之前继续执行当前方法。”
现在我认为这是正确的,也是我想要的。但我有疑问,因为我是异步/等待的新手。 这段代码会按我预期的方式运行,还是会死机或做其他致命的事情?
【问题讨论】:
-
不管怎样,这不还是一劳永逸吗?这不是你想要的吗?
-
如果你在没有等待的情况下调用这个任务返回方法,你仍然是在做一劳永逸的事情。这就是编译器警告的含义。主要区别在于,在第二个示例中,监控逻辑将安排在主上下文/线程上,而第一个示例将使其在线程池上运行。虽然它不应该阻塞线程
标签: c# asynchronous async-await