13

我在我的 WorkerRole (RoleEntryPoint) 中玩任务、异步和等待。

我有一些无法解释的回收,现在我发现如果在等待调用中运行时间过长,角色就会回收。要重现它,只需在 Run 方法中执行 await Task.Delay(60000) 即可。

谁能给我解释一下为什么?

4

2 回答 2

22

Run方法必须阻塞。从文档

如果您确实重写了 Run 方法,您的代码应该无限期地阻塞。如果 Run 方法返回,则通过引发 Stopping 事件并调用 OnStop 方法自动回收角色,以便您的关闭序列可以在角色脱机之前执行。

一个简单的解决方案是这样做:

public override void Run()
{
  RunAsync().Wait();
}

public async Task RunAsync()
{
  while (true)
  {
    await Task.Delay(60000);
  }
}

或者,您可以AsyncContext从我的 AsyncEx 库中使用:

public override void Run()
{
  AsyncContext.Run(async () =>
  {
    while (true)
    {
      await Task.Delay(60000);
    }
  });
}

无论您选择哪个选项,都不Run应该是. 这有点像控制台应用程序(请参阅我的博客了解为什么不允许)。asyncMainasync Main

于 2013-04-13T18:59:49.233 回答
0

我建议使用较低的值,Task.Delay例如 1000 (ms)。我怀疑工人角色无法对健康检查做出足够快的反应。然后该角色被视为无响应并重新启动。

确保该Run方法永远不会以这样的方式返回

while (true)
{               
    Thread.Sleep(1000);
}

或者Task.Delay在你的情况下。

于 2013-04-13T18:53:30.803 回答