mos*_*aka 4 async-await .net-core asp.net-core-hosted-services
.net coreBackgroundService或IHostedService的 start 方法是异步的:
//IHostedService
Task StartAsync(CancellationToken cancellationToken);
//BackgroundService
Task ExecuteAsync(CancellationToken stoppingToken);
Run Code Online (Sandbox Code Playgroud)
那么我应该在ExecuteAsync/StartAsync方法中编写所有逻辑,还是应该启动一个新线程并立即返回?
例如,以下哪两个是正确的实现?
1.
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
new Thread(async () => await DoWork(stoppingToken)).Start();
await Task.CompletedTask;
}
private async Task DoWork(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
//actual works
}
Run Code Online (Sandbox Code Playgroud)
2.
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
//actual works
await Task.Delay(1000);//e.g
}
}
Run Code Online (Sandbox Code Playgroud)
从语义上讲,我认为第二个似乎是正确的,但是如果有几个IHostedServices,它们可以与第二种形式并行运行吗?
编辑 1
我还编写了一个示例程序,说明托管服务本身不是作为单独的线程运行的。
在"Waiting for signal.."我键入 a 之前,不会将消息写入控制台q:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace BackgroundTaskTest
{
public class Program
{
public static async Task Main(string[] args)
{
var host = new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
IConfiguration config = hostContext.Configuration;
//register tasks
services.AddHostedService<ReadService>();
services.AddHostedService<BlockService>();
})
.UseConsoleLifetime()
.Build();
await host.RunAsync();
}
}
public static class WaitClass
{
public static AutoResetEvent Event = new AutoResetEvent(false);
}
public class ReadService : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var c = Console.ReadKey();
if (c.KeyChar == 'q')
{
Console.WriteLine("\nTrigger event");
WaitClass.Event.Set();
}
await Task.Delay(1);
}
}
}
public class BlockService : BackgroundService
{
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
Console.WriteLine("Waiting for signal..");
WaitClass.Event.WaitOne();
Console.WriteLine("Signal waited");
}
return Task.CompletedTask;
}
}
}
Run Code Online (Sandbox Code Playgroud)
只需使用async/实现它await,如您的第二个示例所示。不需要额外的Thread.
旁注:Thread应该只用于 COM 互操作;如今,对于Thread. 只要您输入new Thread,您就已经拥有遗留代码。
| 归档时间: |
|
| 查看次数: |
4390 次 |
| 最近记录: |