5 回答

TA貢獻1876條經(jīng)驗 獲得超7個贊
當(dāng)您使用 Visual Studio 運行它時,您可能會使用 IIS Express,它不會在發(fā)出第一個請求之前運行您的 ASP.NET Core 項目(這實際上就是 IIS 默認(rèn)的工作方式)。這適用于使用 ASP.NET Core 2.2 中新增的 InProcess 托管模型,我希望您必須使用它才能看到此問題。有關(guān)更多信息,請參閱此GitHub 問題。
您可以通過從用于托管 ASP.NET Core 應(yīng)用程序的 .csproj 文件中刪除 AspNetCoreHostingModel XML 元素來證明這一理論(這會將其切換回 OutOfProcess 模式)??雌饋鞻S2017的項目屬性對話框中的“調(diào)試”下有一個“托管模型”選項,如果您不想直接編輯.csproj,可以將其更改為“進程外”。
例如,如果您希望托管模型僅用于生產(chǎn)站點的進程外,則可以使用 Web.config 轉(zhuǎn)換。如果您希望它在開發(fā)和生產(chǎn)過程中都處于進程外,只需更改我在上面調(diào)用的屬性就足夠了,因為它會自動轉(zhuǎn)換為 Web.config 屬性。如果您希望使用進程內(nèi)模型,在 IIS 應(yīng)用程序中啟用預(yù)加載是一個不錯的選擇(在此處描述)。

TA貢獻1824條經(jīng)驗 獲得超8個贊
后臺服務(wù)在您的應(yīng)用程序啟動時啟動,然后由您決定與之同步。
您可以使用命名空間(程序集)中的BackgroundService類來實現(xiàn)后臺服務(wù):Microsoft.Extensions.HostingMicrosoft.Extensions.Hosting.Abstractions
首先聲明你的服務(wù)的接口(在這種情況下它是空的,不是很好,但很干凈):
public interface IMyService : IHostedService
{
}
然后,聲明您的服務(wù)。以下代碼段聲明了一個服務(wù),該服務(wù)在啟動時持續(xù) 5 秒,然后每 2 分半鐘執(zhí)行一次任務(wù):
internal sealed class MyService : BackgroundService, IMyService
{
private const int InitialDelay = 5 * 1000; //5 seconds;
private const int Delay = (5 * 60 * 1000) / 2; // 2.5 minutes
private readonly ILogger<MyService> m_Logger;
public MyService(ILogger<MyService> logger, IServiceProvider serviceProvider)
{
if (logger == null)
throw new ArgumentNullException(nameof(logger));
if (serviceProvider == null)
throw new ArgumentNullException(nameof(serviceProvider));
this.m_Logger = logger;
this.m_ServiceProvider = serviceProvider;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
m_Logger.LogDebug($"MyService is starting.");
stoppingToken.Register(() => m_Logger.LogDebug($"MyService background task is stopping because cancelled."));
if (!stoppingToken.IsCancellationRequested)
{
m_Logger.LogDebug($"MyService is waiting to be scheduled.");
await Task.Delay(InitialDelay, stoppingToken);
}
m_Logger.LogDebug($"MyService is working.");
while (!stoppingToken.IsCancellationRequested)
{
await DoSomethingAsync();
await Task.Delay(Delay);
}
m_Logger.LogDebug($"MyService background task is stopping.");
}
catch (Exception ex)
{
m_Logger.LogDebug("MyService encountered a fatal error while w task is stopping: {Exception}.", ex.ToString());
}
}
private async Task DoSomethingAsync()
{
// do something here
await Task.Delay(1000);
}
}
如您所見,讓后臺服務(wù)“活動”取決于您。最后,您必須在您的方法Startup.cs結(jié)束時將其注冊ConfigureServices:
services.AddSingleton<Microsoft.Extensions.Hosting.IHostedService, MyService>();
這足以啟動服務(wù)。請記住,如果托管在 IIS 中,您的應(yīng)用程序?qū)嶋H上可能會在以后啟動:每次回收程序集時,您的應(yīng)用程序都會(重新)啟動。相反,使用 Kestrel 提供了一個不會被回收的單實例應(yīng)用程序。
對于那些使用 .Net Core 2.1 或更低版本的人,Background 類不可用,但您可以從 github 獲取定義(我發(fā)布了我過去使用的內(nèi)容,因為 github 存儲庫可以移動):
//borrowed from .NET Core 2.1 (we are currently targeting 2.0.3)
// Copyright (c) .NET Foundation. Licensed under the Apache License, Version 2.0.
/// <summary>
/// Base class for implementing a long running <see cref="IHostedService"/>.
/// </summary>
public abstract class BackgroundService : IHostedService, IDisposable
{
private Task _executingTask;
private readonly CancellationTokenSource _stoppingCts =
new CancellationTokenSource();
protected abstract Task ExecuteAsync(CancellationToken cancellationToken);
public virtual Task StartAsync(CancellationToken cancellationToken)
{
// Store the task we're executing
_executingTask = ExecuteAsync(_stoppingCts.Token);
// If the task is completed then return it,
// this will bubble cancellation and failure to the caller
if (_executingTask.IsCompleted)
{
return _executingTask;
}
// Otherwise it's running
return Task.CompletedTask;
}
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
if (_executingTask == null)
{
return;
}
try
{
// Signal cancellation to the executing method
_stoppingCts.Cancel();
}
finally
{
// Wait until the task completes or the stop token triggers
await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite,
cancellationToken));
}
}
public virtual void Dispose()
{
_stoppingCts.Cancel();
}
}

TA貢獻1848條經(jīng)驗 獲得超6個贊
如果您想要一個服務(wù)來執(zhí)行后臺任務(wù)(類似于舊的 Windows 服務(wù)),我建議您使用:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host? view=aspnetcore-2.2而不是 WebHost。
WebHost 添加了很多您可能不需要的東西,因為這似乎是一個簡單的后臺工作(假設(shè)閱讀您的代碼)。

TA貢獻1853條經(jīng)驗 獲得超6個贊
對我來說......后臺任務(wù)直到第一頁請求才開始。
但后來我注意到在我的發(fā)布/編輯中,我沒有設(shè)置目標(biāo)網(wǎng)址。(而且我沒有主頁索引頁面)......
一旦我添加了一個有效的目標(biāo)網(wǎng)址......該頁面將在發(fā)布后彈出并成為我的“第一個”頁面請求,后臺任務(wù)將開始。

TA貢獻1821條經(jīng)驗 獲得超6個贊
托管服務(wù)確實在主機啟動時啟動。使用 WebHost,托管服務(wù)將在應(yīng)用程序啟動后立即啟動。這意味著如果實施得當(dāng),您的托管服務(wù)將無需請求即可運行。
當(dāng)我在一個新的 ASP.NET Core 應(yīng)用程序上嘗試你的示例托管服務(wù)時,它工作得很好,所以如果它不適合你,那么顯然你的實際實現(xiàn)KontolerTimer
是不正確的。
- 5 回答
- 0 關(guān)注
- 181 瀏覽
添加回答
舉報