.Net核心后台服务和长时间运行的任务
我使用.NETCore在ASP.NETCore中运行长时间运行的后台服务和长时间运行的任务,以便在LinuxUbuntu18.04中获得外部运行进程生成的文件。使用FileSystemWatcher 24小时或更长时间后,情况变得更糟。FileSystemWatch工作正常,但长时间运行的线程和后台服务工作不正常,有时它们会毫无错误地停止 任何人都对.NETCore3.1中的后台服务或长时间运行的任务问题有想法 我应该使用Hangfire来避免这些问题吗 示例:此线程可以不停止工作72小时.Net核心后台服务和长时间运行的任务,.net,asp.net-core,.net-core,.net,Asp.net Core,.net Core,我使用.NETCore在ASP.NETCore中运行长时间运行的后台服务和长时间运行的任务,以便在LinuxUbuntu18.04中获得外部运行进程生成的文件。使用FileSystemWatcher 24小时或更长时间后,情况变得更糟。FileSystemWatch工作正常,但长时间运行的线程和后台服务工作不正常,有时它们会毫无错误地停止 任何人都对.NETCore3.1中的后台服务或长时间运行的任务问题有想法 我应该使用Hangfire来避免这些问题吗 示例:此线程可以不停止工作72小时
public class DataByteCollector{
public readonly BytesMemoryCache DataBytesMemoryCache;
public DataByteCollector(BytesMemoryCache DataBytesMemoryCache)
{
DataBytesMemoryCache = DataBytesMemoryCache;
}
public BufferBlock<ByteData> ByteStream { get; set; }
public async Task SubscribeToStream(string bytesId, CancellationToken cancellationToken)
{
// Avoid Capturing members in anonymous methods
var DataBytesMemoryCache = DataBytesMemoryCache;
ByteStream = new BufferBlock<ByteData>(
new DataflowBlockOptions
{
BoundedCapacity = 8,
EnsureOrdered = true,
CancellationToken = cancellationToken
});
var byteStream = ByteStream;
var streamDataCache = DataBytesMemoryCache.GetBytesCache(bytesId);
if (streamDataCache == null)
{
ByteStream.Complete();
return;
}
var bytesData = streamDataCache.Streams;
async Task DataGathring()
{
try
{
DateTime? lastDataRead = null;
var hasStarted = true;
while (!cancellationToken.IsCancellationRequested && DataBytesMemoryCache.DataCacheExists(bytesId))
{
IEnumerable<ByteData> stat;
if (hasStarted)
{
stat = bytesData.ToArray();
hasStarted = false;
}
else
{
stat = bytesData.TakeLast(1).Where(x => x.DateTime > lastDataRead).ToArray();
}
if (stat.Any())
{
foreach (var farge in stat)
{
lastDataRead = DateTime.Now;
await Channel.SendAsync(farge, cancellationToken);
}
}
else
{
await byteStream.SendAsync(new ByteData(new byte[100], "dummy"), cancellationToken);
}
if (lastDataRead == null)
{
break;
}
if (lastDataRead < DateTime.Now.AddSeconds(-30))
{
break;
}
await Task.Delay(5000, cancellationToken);
}
cancellationToken.ThrowIfCancellationRequested();
byteStream.Complete();
await byteStream.Completion;
}
catch (Exception e)
{
byteStream.Complete();
await byteStream.Completion;
}
}
await Task.Factory.StartNew(DataGathring, cancellationToken);
}
}
公共类数据单元收集器{
公共只读字节内存缓存数据字节内存缓存;
公共DataByteCollector(BytesMemoryCache DataBytesMemoryCache)
{
DataBytesMemoryCache=DataBytesMemoryCache;
}
公共BufferBlock ByTestStream{get;set;}
公共异步任务SubscribeToStream(字符串bytesId,CancellationToken CancellationToken)
{
//避免在匿名方法中捕获成员
var DataBytesMemoryCache=databytesmorycache;
ByteStream=新缓冲块(
新的DataflowBlockOptions
{
边界容量=8,
EnsureOrdered=true,
CancellationToken=CancellationToken
});
var byteStream=byteStream;
var streamDataCache=databytemorycache.GetBytesCache(bytesId);
if(streamDataCache==null)
{
ByteStream.Complete();
返回;
}
var bytesData=streamDataCache.Streams;
异步任务DataGathring()
{
尝试
{
DateTime?lastDataRead=null;
var hasStarted=真;
而(!cancellationToken.IsCancellationRequested&&DataBytesMemoryCache.DataCacheExists(bytesId))
{
IEnumerable stat;
如果(已启动)
{
stat=bytesData.ToArray();
hasStarted=false;
}
其他的
{
stat=bytesData.TakeLast(1).Where(x=>x.DateTime>lastDataRead.ToArray();
}
if(stat.Any())
{
foreach(var farge统计)
{
lastDataRead=DateTime.Now;
wait Channel.SendAsync(farge,cancellationToken);
}
}
其他的
{
wait byteStream.SendAsync(新字节数据(新字节[100],“伪”),cancellationToken);
}
if(lastDataRead==null)
{
打破
}
if(lastDataRead
为什么不为此使用IHostedService
发布您的代码。你让人们猜出发生了什么。如果FSW将事件发布到后台服务检查的队列,则不应存在任何长时间运行的线程。您是否在后台服务中添加了异常处理和日志记录?这是找出问题所在、哪些事件已被处理或未处理、哪些事件失败等的唯一方法。实际代码仍然缺失。这不是一个线程,这是一个每5秒休眠一次的任务。延续是在线程池线程上处理的,几乎可以肯定每次都会不同。该延续是
/
省略的代码。那么这段代码做什么呢?如果你想监控长时间运行的作业,你需要跟踪的不仅仅是错误。至少,每次执行的完成,甚至可能是在较低的级别开始。处理时间也很重要。这将允许您跟踪何时执行的内容、所用的时间,并检测处理时间是否意外增加。后台/托管服务没有问题(它们指的是同一件事)。Hangfire提供了更多的调度和监控机制。你还没有发布你的代码,所以你不可能猜到哪里出了问题,或者你想做什么-控制器是如何参与后台服务的?如果您想将工作从控制器发布到服务,您需要以某种方式连接它们,可能是通过队列。A可以用来做那份工作,让你摆脱looping@PanagiotisKanavos例如我必须使用订阅方法。。稍后在响应流正文中发送收集的字节“BufferBlock”。因为当用户请求它时,我必须在控制器中使用它。@TLEJMI控制器应该发送到由托管服务监控的队列。我想这就是你在写长期运行的后台服务时的意思。请求线程不能长时间运行。@tiejmi除了通过AddHostedService
注册托管服务外,您还可以将托管服务注册为单例并通过普通DI使用它,这可能是您想要的答案