如何在C#Async/Await应用程序中创建循环服务?

Jam*_*oux 2 c# asynchronous async-await

我编写了一个类,该方法在线程池中作为长时间运行的Task运行.该方法是一种监视服务,用于定期发出REST请求以检查另一个系统的状态.它只是一个while()循环,里面有一个try()catch(),这样它就可以处理自己的异常,并在发生意外情况时正常继续.

这是一个例子:

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...");
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我想知道是否有另一种模式我可以使用它将允许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...");
            }
        }

    }
Run Code Online (Sandbox Code Playgroud)

但是当我尝试在另一个异步方法中调用该方法时,我得到了有趣的编译器警告:

"因为没有等待这个调用,所以在调用完成之前,当前方法的执行仍在继续."

现在我认为这是正确的,我想要的.但我怀疑是因为我是async/await的新手.这段代码是按照我预期的方式运行还是以DEADLOCK或其他致命的方式运行?

Igo*_*gor 6

你真正想要的是使用Timer.使用System.Threading命名空间中的那个.无需使用Task或任何其他变体(对于您显示的代码示例).

private System.Threading.Timer timer;
void StartTimer()
{
    timer = new System.Threading.Timer(TimerExecution, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));
}

void TimerExecution(object state)
{
    try
    {
        //Check system status
    }
    catch (Exception e)
    {
        Console.WriteLine("An error occurred. Resuming on next loop...");
    }
}
Run Code Online (Sandbox Code Playgroud)

从文档中

提供以指定的时间间隔在线程池线程上执行方法的机制


您也可以使用System.Timers.Timer,但您可能不需要它.有关2个定时器之间的比较,另请参阅System.Timers.Timer与System.Threading.Timer.