我有運行服務的 Linux 背景,第一次在 Microsoft 環境中作業。我敢肯定,代碼可以在許多方面得到改進,第一步是獲得正在運行的服務。我已經參考了許多帖子和檔案,但與使用 apache 運行 django 應用程式的 linux 環境相比,我還不能完全理解 Microsoft 服務和 dotnet 如何互動。
我使用 Visual Basic for Mac 作為開發,dotnet 5.0 C# 環境來構建一個服務,該服務偵聽目錄以創建新檔案,然后運行帶有檔案資訊的腳本。我部署到帶有 dotnet 5.0 環境的 Windows 10 x-64。我可以編譯一個 .exe 并在目標機器上運行,它作業正常。然后我使用 sc.exe 構建服務,無論我是從服務管理器 GUI 還是從 Powershell 運行,該服務總是會超時。我想弄清楚如何讓服務繼續運行。該服務將寫入我的日志檔案,如果新檔案添加到目標目錄,它甚至會處理該檔案,但它總是會繼續超時并出現以下錯誤:
Error 1053: the service did not respond to the start or control request in a timely fashion
我的步驟和代碼如下:
使用 Visual Studio for Mac 創建作業服務。
MyProgram.cs是從模板構建的,并添加了一些其他現在為空的方法,但我認為會很有用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace MyService
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
//config.AddJsonFile("custom_settings.json");
})
.ConfigureLogging(logging =>
{
//builder.AddFile("logs/app-{Date}.json"), isJson: true);
})
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
}
}
接下來是Worker.cs:
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using HttpClientSample;
namespace MyService
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
public override async Task StartAsync(CancellationToken cancellationToken)
{
string path = @"C:\log.txt";
string startText = "Start" Environment.NewLine;
File.AppendAllText(path, startText);
await ExecuteAsync(cancellationToken);
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
string path = @"C:\log.txt";
string stopText = "Stop" Environment.NewLine;
File.AppendAllText(path, stopText);
await base.StopAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
string path = @"C:\log.txt";
string writeText = "Execute Async" Environment.NewLine;
File.AppendAllText(path, writeText);
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = @"C:\files\";
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Created = OnCreated;
watcher.Filter = "*.*";
watcher.EnableRaisingEvents = true;
File.AppendAllText(path, "watcher engaged.");
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("worker running at: {time}", DateTimeOffset.Now);
try
{
await Task.Delay(1000, stoppingToken);
}
catch (OperationCanceledException)
{
break;
}
}
}
private static void OnCreated(object sender, FileSystemEventArgs e)
{
string path = @"C:\log.txt";
string writeText = $"e: {e}";
File.AppendAllText(path, writeText);
MyProgram myProgram = new MyProgram(e.FullPath);
}
}
}
然后我在 MyProgram 中進行處理,一切正常。
對于該服務,我首先使用以下命令編譯以更正運行時:dotnet publish -c Release -r win10-x64. 然后我將發布檔案夾通過 FTP 傳輸到 Windows 10 機器,運行 .exe 作為管理員組態檔并且它作業正常,然后通過以下方式從檔案創建服務:sc.exe create myService binPath= "C:\path\to\executable.exe". 然后我繼續從服務管理器或從 Powershell 使用sc.exe start myService. 大約 60 秒后,我收到 1053 錯誤。
我不明白保持服務運行需要什么。我在下面嘗試過的步驟:
- 我確保在構建服務時指向 exe。
- I've already increased the timeout via registry as suggested in several sites: here.
- I've checked in the Event Viewer for dotnet or services manager issues and wasn't able to find the cause of the issue.
- I've tried the local system account as well as admin account to run the service and it still times out.
- I've seen InstallUtil as a suggested alternative to sc.exe, but I haven't tried it. I'm not sure how much a difference the tool makes?
- Would using the WindowsService vs BackgroundService make the difference when trying to run this via Services Manager?
- 是否有一些程式需要實作的信號或回傳值,以便讓服務知道繼續運行?已經實作了 Task.delay() 并為 StartTask 和 ExecuteTask 方法回傳值。
任何有關故障排除、解決問題或改進我的帖子的建議都將不勝感激。謝謝!
uj5u.com熱心網友回復:
服務行程必須呼叫正確的 dll 函式來指示它正在啟動,并接收暫停/停止事件。
在 .net 中有這些 dll 呼叫的實作內置到 System.ServiceProcess.ServiceBase
有一個內置于 asp.net 的服務的實作,我相信它早于通用主機的引入。只需呼叫IWebHost.RunAsService()就足以將 Windows 服務啟動/停止事件粘合到 Web 主機啟動/停止生命周期中。
我相信您需要做的就是.UseWindowsService()在配置主機構建器時呼叫。這應該適用于控制臺程式或網路主機。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/313589.html
上一篇:從集合中檢索隨機檔案
下一篇:如何根據條件訪問類屬性
