【发布时间】:2020-12-14 00:16:57
【问题描述】:
我在后台服务中使用 Task.Run。我有后台服务,负责特定系统的登录和发送心跳。
public class TestBGService : IHostedService
{
private readonly ITestService _testService;
private bool MustLogOn { get; set; } = true;
private string id { get; set; }
public TestBGService(ITestService testService)
{
_testService = testService;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
Log.Information("TestBGService starts Initialize");
await Initialize();
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
private async Task Initialize()
{
try
{
if (MustLogOn)
{
Log.Information("TestBGService ExecuteAsync trying to LogOnAsync");
id = await _testService.LogOnAsync();
if (!string.IsNullOrEmpty(id))
{
Log.Information($"new id equals to {id}");
MustLogOn = false;
_ = Task.Run(async () =>
{
while (true)
{
bool res = await SendHeartBeat(id);
Log.Information($"res from SendHeartBeat {res}");
if (!res)
{
break;
}
await Task.Delay(10000);
}
});
await _testService.StartProcessAsync(id);
}
}
}
catch (Exception ex)
{
Log.Error($"TestBGService ExecuteAsync throws {ex.ToString()}");
}
}
private async Task<bool> SendHeartBeat(string id)
{
bool isSuccess = true;
try
{
Log.Information("TestBGService sending heartbeat at " + DateTime.Now);
var response = new HeartBeatResponseModel();
response = await _testService.SendHeartBeatAsync(id);
Log.Information("TestBGService heartbeat response equals to " + response.IsSuccessful);
if (!response.IsSuccessful)
{
MustLogOn = true;
isSuccess = response.IsSuccessful;
}
}
catch (Exception ex)
{
Log.Error(ex, "TestBGService SendHeartBeat throws");
isSuccess = false;
MustLogOn = true;
}
return isSuccess;
}
}
Initialize 方法尝试LogOn 到系统,在成功的情况下,它需要启动SendHeartBeat。 SendHeartBeat 方法负责获取成功或失败。如果成功,我将 MustLogon 的值更改为 false 并每 10 秒发送一次 SendHeartBeat。 SendHeartBeat 的并行我需要调用_testService.StartProcessAsync 从流中获取数据。不知何故它停止工作并再次启动 LogOn 但我需要它直到它返回 false 它应该工作并且 SendHeartBeat 需要每 10 秒完成一次但不幸的是,它在 bool res = true 的情况下停止工作并且此刻它不会抛出任何例外。有什么建议吗?
【问题讨论】:
-
看看这个例子:docs.microsoft.com/en-us/aspnet/core/fundamentals/host/… 并尝试相应地修改您的代码。你不应该永远在 StartAsync 方法中徘徊。
-
Fildor,当我发送cancellationToken时它停止
-
是的,因为这是垃圾(抱歉)。请查看定时服务应该如何工作(请参阅第一条评论中的链接)。在 Timer Callback 中: 1. 如果需要,请登录, 2. SendHeartBeat。完毕。不要从任务中开始任务...
-
或者您可以从提供的链接@Fildor 中快速使用
BackgroundService,将您的“Initialize”逻辑移动到ExecuteAsync(并删除Task.Run这里有什么意义?)。 -
没有什么能阻止你这样做。
标签: c# asp.net .net multithreading task-parallel-library