我使用Topshelf的Owin Web服务器启动休息服务器。在同一个服务中,我想启动一个后台任务来轮询(是的,我必须轮询!)一个数据库,用于"云命令"然后将数据写入锁定代码中的云。
此代码似乎在一段时间后停止处理owin请求(它们似乎被拒绝),我不知道为什么?
StartMethod调用CheckForCloudCommandsForever,后者又在无限循环中调用ProcessPostedCommands。我参考了代码中嵌入的研究,以展示我如何到达今天的代码。
启动背景无限循环的正确方法是什么?
公共类WebServer { 私人IDisposable _webapp;
// Do not call with await for it to loop forever
private async Task CheckForCloudCommandsForever()
{
InitCloud();
var cmdRdr = new FwCommandReader();
while (true)
{
// do the work in the loop
string newData = DateTime.Now.ToLongTimeString();
//GlobalLogger.Logger.Debug($"In Loop {newData}");
cmdRdr.ProcessPostedCommands();
// don't run again for at least x milliseconds
await Task.Delay(3000);
}
}
public void Start()
{
// https://blogs.msdn.microsoft.com/benwilli/2016/06/30/asynchronous-infinite-loops-instead-of-timers/
// invoke loop method but DO NOT await it so the rest of the program can run
CheckForCloudCommandsForever();
// _webapp = WebApp.Start<Startup>("http://*:8080");
/*
* from SO http://stackoverflow.com/questions/21634333/hosting-webapi-using-owin-in-a-windows-service
*/
StartOptions options = new StartOptions();
//string portPrime = "52017";
string portPrime = FWUtils.ConfigUtils.SrcPort();
options.Urls.Add("http://*:" + portPrime);
string machineAndPort = $"http://{Environment.MachineName}:{portPrime}";
options.Urls.Add(machineAndPort);
Console.WriteLine($"FWShowServer starting up on URL={machineAndPort}.");
try
{
_webapp = WebApp.Start<Startup>(options);
}
catch (Exception e)
{
Console.WriteLine(e);
Console.WriteLine($"Service could not open on Port={machineAndPort}, Make sure you are a system admin or perhaps the port is already used. Create and or edit the server config file to specify an unused port.");
throw;
}
}
public void ProcessPostedCommands() { 使用(var showContext = new ShowContext()) {
var commands = showContext.CloudCommands
.Where(c => !showContext.CloudCommandsProcessed
.Select(p => p.CloudCommandsPKID)
.Contains(c.Pkid)
)
//.OrderByDescending( c => c.SubmittedAt)
.OrderBy( c => c.SubmittedAt)
.ToList();
foreach (var command in commands)
{
lock (cloudLock)
{
if (executingTask == null || executingTask.IsCompleted)
{
executingTask = ProcessCommandAsync(showContext, command);
}
}
executingTask.Wait();
}
}
}