这是一个循环的好技巧。
对于初学者,如果您不希望应用程序自我毁灭并保持打开状态以进入 2018 年 - 让我们成为 HostBuilder!
您可以让应用程序启动和保持并保持异步,赢得胜利,例如,这里是我最近的事件引擎的主要入口点:
public static async Task Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
var startup = new Startup();
var hostBuilder = new HostBuilder()
.ConfigureHostConfiguration(startup.ConfigureHostConfiguration)
.ConfigureAppConfiguration(startup.ConfigureAppConfiguration)
.ConfigureLogging(startup.ConfigureLogging)
.ConfigureServices(startup.ConfigureServices)
.Build();
await hostBuilder.RunAsync();
}
将 nuget 包引用添加到 Microsoft.Extensions.Hosting。
如果你现在有 DI 需要整理,你可以跳过所有的 startup... 行。
您还需要将此行添加到您的项目文件中:
<LangVersion>latest</LangVersion>
一旦应用运行,任何 IHostedService 实现都会自动运行。
我把我的控制台代码放在这里,所以这是我的例子:
using MassTransit;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Trabalhos.EventsEngine.Messages;
namespace Trabalhos.EventsEngine.ClientExample
{
public class SenderHostedService : IHostedService
{
private readonly IBusControl eventsEngine;
private readonly ILogger<SenderHostedService> logger;
public SenderHostedService(IBusControl eventsEngine, ILogger<SenderHostedService> logger)
{
this.eventsEngine = eventsEngine;
this.logger = logger;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
var products = new List<(string name, decimal price)>();
Console.WriteLine("Welcome to the Shop");
Console.WriteLine("Press Q key to exit");
Console.WriteLine("Press [0..9] key to order some products");
Console.WriteLine(string.Join(Environment.NewLine, Products.Select((x, i) => $"[{i}]: {x.name} @ {x.price:C}")));
for (;;)
{
var consoleKeyInfo = Console.ReadKey(true);
if (consoleKeyInfo.Key == ConsoleKey.Q)
{
break;
}
if (char.IsNumber(consoleKeyInfo.KeyChar))
{
var product = Products[(int)char.GetNumericValue(consoleKeyInfo.KeyChar)];
products.Add(product);
Console.WriteLine($"Added {product.name}");
}
if (consoleKeyInfo.Key == ConsoleKey.Enter)
{
await eventsEngine.Publish<IDummyRequest>(new
{
requestedData = products.Select(x => new { Name = x.name, Price = x.price }).ToList()
});
Console.WriteLine("Submitted Order");
products.Clear();
}
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
private static readonly IReadOnlyList<(string name, decimal price)> Products = new List<(string, decimal)>
{
("Bread", 1.20m),
("Milk", 0.50m),
("Rice", 1m),
("Buttons", 0.9m),
("Pasta", 0.9m),
("Cereals", 1.6m),
("Chocolate", 2m),
("Noodles", 1m),
("Pie", 1m),
("Sandwich", 1m),
};
}
}
这将启动、运行并保持运行。
这里很酷的地方也是 for(;;) 循环,这是一个巧妙的技巧,可以让它在循环上运行,这样你就可以一遍又一遍地重新做事情,托管只是意味着你不需要担心保持控制台活着。
我什至有你想要的转义键:
if (consoleKeyInfo.Key == ConsoleKey.Q)
{
break;
}
有关使用托管设置的深入示例,请使用此链接https://jmezach.github.io/2017/10/29/having-fun-with-the-.net-core-generic-host/
浏览一遍应该会有所帮助。