如何解决在backgroundservice中运行Task.Run意外停止工作
我在backgroundservice内部使用Task.Run。我有后台服务,负责特定系统的登录和发送HeartBeat。
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;
}
}
初始化方法以尝试登录系统,如果成功,则需要启动SendHeartBeat。 SendHeartBeat方法负责获取成功或失败。如果成功,我会将Mustlogon的值更改为false,并每10秒发送一次SendHeartBeat。 SendHeartBeat的并行处理我需要调用_testService.StartProcessAsync
从流中获取数据。它以某种方式停止工作,并再次启动logon,但是我需要它直到返回false为止,它应该可以工作,并且SendHeartBeat需要每10秒完成一次,但是不幸的是,如果出现bool res = true
,它会停止工作,而此时此刻不起作用抛出任何异常。有什么建议吗?
解决方法
这是我根据BackgroundService base class中的链接想到的,并“插入”了您所需的功能:(当然,未经测试)
public class TestBGService : BackGroundService
{
// I guess you are using different logging
private readonly ILogger<TestBGService> _logger;
// Your service to send Heartbeats to
private readonly ITestService _testService;
// If id is null,we need to login.
private string _id = null;
public TestBGService (ILogger<TestBGService> logger,ITestService testService)
{
_logger = logger;
_testService = testService ?? throw new ArgumentNullException(nameof(testService));
}
public Task StartAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("TestBGService running.");
return Task.CompletedTask;
}
// This will be triggered by the runtime.
private async Task ExecuteAsync (System.Threading.CancellationToken stoppingToken)
{
while( !stoppingToken.CancellationRequested )
{
try
{
if( string.IsNullOrEmpty(_id) )
{
// _id is null => perform login
_id = await _testService.LogOnAsync(); // perhaps pass stoppingToken?
}
bool res = await SendHeartBeat(id); // again: consider passing stoppingToken
if( !res ) _id = null; // Heartbeat unsuccessful: login next time
await Task.Delay(TimeSpan.FromSeconds(10),stoppingToken);
}
catch(Exception ex) // You should actually catch more specific exceptions.
{
// TODO log Exception
_id = null; // Reset id,so we login next time.
}
}
}
private async Task<bool> SendHeartBeat(string id)
{
// Don't even try if login was unsuccessful.
if ( string.IsNullOrEmpty(id) ) return false;
_logger.LogInformation("TestBGService sending heartbeat at {0}",DateTime.Now);
var response = await _testService.SendHeartBeatAsync(id);
_logger.LogInformation("TestBGService heartbeat response {0}successful",response.IsSuccessful ? "" : "un");
return response.IsSuccessful;
}
public Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("TestBGService is stopping.");
// TODO maybe explicit logout?
return Task.CompletedTask;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。