解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
10.75 KiB
X
# ÇáÁ¿¼¶Ó¦ÓÃÖ÷»ú Host ## ¸ÅÊö `Host` ÊÇ NewLife.Core ÖеÄÇáÁ¿¼¶Ó¦ÓÃÖ÷»ú£¬ÌṩӦÓóÌÐòÉúÃüÖÜÆÚ¹ÜÀí¹¦ÄÜ¡£Ö§³ÖÍйܶà¸öºǫ́·þÎñ£¬×Ô¶¯´¦ÀíÆô¶¯¡¢Í£Ö¹¡¢ÓÅÑÅÍ˳öµÈ³¡¾°£¬ÌرðÊʺϿØÖÆÌ¨Ó¦Óᢺǫ́·þÎñ¡¢Î¢·þÎñµÈ³¡¾°¡£ **ÃüÃû¿Õ¼ä**£º`NewLife.Model` **ÎĵµµØÖ·**£ºhttps://newlifex.com/core/host ## ºËÐÄÌØÐÔ - **·þÎñÍйÜ**£ºÖ§³Ö×¢²áºÍ¹ÜÀí¶à¸ö `IHostedService` ·þÎñ - **ÉúÃüÖÜÆÚ¹ÜÀí**£º×Ô¶¯´¦ÀíÆô¶¯¡¢Í£Ö¹¡¢Òì³£»Ø¹ö - **ÓÅÑÅÍ˳ö**£ºÏìÓ¦ Ctrl+C¡¢SIGINT¡¢SIGTERM µÈϵͳÐźŠ- **¿çƽ̨**£ºÖ§³Ö Windows¡¢Linux¡¢macOS - **ÒÀÀµ×¢Èë**£ºÓë `ObjectContainer` Éî¶È¼¯³É - **³¬Ê±¿ØÖÆ**£ºÖ§³ÖÉèÖÃ×î´óÔËÐÐʱ¼ä ## ¿ìËÙ¿ªÊ¼ ```csharp using NewLife.Model; // ´´½¨Ö÷»ú var host = new Host(ObjectContainer.Provider); // Ìí¼Óºǫ́·þÎñ host.Add<MyBackgroundService>(); host.Add<AnotherService>(); // ÔËÐУ¨×èÈûÖ±µ½ÊÕµ½Í˳öÐźţ© host.Run(); ``` ## API ²Î¿¼ ### IHostedService ½Ó¿Ú ºǫ́·þÎñ±ØÐëʵÏִ˽ӿڣº ```csharp public interface IHostedService { /// <summary>¿ªÊ¼·þÎñ</summary> Task StartAsync(CancellationToken cancellationToken); /// <summary>Í£Ö¹·þÎñ</summary> Task StopAsync(CancellationToken cancellationToken); } ``` **ʵÏÖʾÀý**£º ```csharp public class MyBackgroundService : IHostedService { private CancellationTokenSource? _cts; private Task? _task; public Task StartAsync(CancellationToken cancellationToken) { XTrace.WriteLine("MyBackgroundService Æô¶¯"); _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); _task = ExecuteAsync(_cts.Token); return Task.CompletedTask; } public async Task StopAsync(CancellationToken cancellationToken) { XTrace.WriteLine("MyBackgroundService Í£Ö¹"); _cts?.Cancel(); if (_task != null) await Task.WhenAny(_task, Task.Delay(5000, cancellationToken)); } private async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { // Ö´Ðкǫ́ÈÎÎñ XTrace.WriteLine("ºǫ́ÈÎÎñÖ´ÐÐÖÐ..."); await Task.Delay(1000, stoppingToken); } } } ``` ### Host Àà #### ¹¹Ô캯Êý ```csharp public Host(IServiceProvider serviceProvider) ``` ͨ¹ý·þÎñÌṩÕß´´½¨Ö÷»úʵÀý¡£ **ʾÀý**£º ```csharp // ʹÓÃÈ«¾ÖÈÝÆ÷ var host = new Host(ObjectContainer.Provider); // ʹÓÃ×Ô¶¨ÒåÈÝÆ÷ var ioc = new ObjectContainer(); ioc.AddSingleton<ILogger, ConsoleLogger>(); var host = new Host(ioc.BuildServiceProvider()); ``` #### Add - Ìí¼Ó·þÎñ ```csharp // Ìí¼Ó·þÎñÀàÐÍ void Add<TService>() where TService : class, IHostedService // Ìí¼Ó·þÎñʵÀý void Add(IHostedService service) ``` **ʾÀý**£º ```csharp var host = new Host(ObjectContainer.Provider); // ͨ¹ýÀàÐÍÌí¼Ó host.Add<MyBackgroundService>(); host.Add<DataSyncService>(); // ͨ¹ýʵÀýÌí¼Ó var service = new CustomService(config); host.Add(service); ``` #### Run / RunAsync - ÔËÐÐÖ÷»ú ```csharp // ͬ²½ÔËÐУ¨×èÈû£© void Run() // Òì²½ÔËÐÐ Task RunAsync() ``` ÔËÐÐÖ÷»ú£¬Æô¶¯ËùÓзþÎñ£¬È»ºó×èÈûµÈ´ýÍ˳öÐźš£ **ʾÀý**£º ```csharp // ͬ²½ÔËÐÐ host.Run(); // Òì²½ÔËÐÐ await host.RunAsync(); // Òì²½ÔËÐкó¼ÌÐøÆäËû²Ù×÷ _ = host.RunAsync(); // ÆäËû´úÂë... ``` #### StartAsync / StopAsync ```csharp Task StartAsync(CancellationToken cancellationToken) Task StopAsync(CancellationToken cancellationToken) ``` ÊÖ¶¯¿ØÖÆÆô¶¯ºÍÍ£Ö¹¡£ **ʾÀý**£º ```csharp using var cts = new CancellationTokenSource(); // Æô¶¯·þÎñ await host.StartAsync(cts.Token); // ×öһЩ¹¤×÷... await Task.Delay(10000); // ÊÖ¶¯Í£Ö¹ await host.StopAsync(cts.Token); ``` #### Close - ¹Ø±ÕÖ÷»ú ```csharp void Close(String? reason) ``` Ö÷¶¯¹Ø±ÕÖ÷»ú£¬´¥·¢Í£Ö¹Á÷³Ì¡£ **ʾÀý**£º ```csharp // ij¸öÌõ¼þ´¥·¢¹Ø±Õ if (shouldShutdown) { host.Close("Ìõ¼þ´¥·¢¹Ø±Õ"); } ``` #### MaxTime ÊôÐÔ ```csharp public Int32 MaxTime { get; set; } = -1; ``` ×î´óÖ´ÐÐʱ¼ä£¨ºÁÃ룩¡£Ä¬ÈÏ -1 ±íʾÓÀ¾ÃÔËÐС£ **ʾÀý**£º ```csharp var host = new Host(ObjectContainer.Provider); host.MaxTime = 60_000; // ×î¶àÔËÐÐ60Ãë host.Add<MyService>(); host.Run(); // 60Ãëºó×Ô¶¯Í£Ö¹ ``` ### ¾²Ì¬·½·¨ #### RegisterExit - ×¢²áÍ˳öʼþ ```csharp // ¿ÉÄܱ»¶à´Îµ÷Óà static void RegisterExit(EventHandler onExit) // ½öÖ´ÐÐÒ»´Î static void RegisterExit(Action onExit) ``` ×¢²áÓ¦ÓÃÍ˳öʱµÄ»Øµ÷º¯Êý¡£ **ʾÀý**£º ```csharp // ×¢²áÍ˳öÇåÀíº¯Êý Host.RegisterExit(() => { XTrace.WriteLine("Ó¦ÓÃÕýÔÚÍ˳ö£¬Ö´ÐÐÇåÀí..."); CleanupResources(); }); // ´ø²ÎÊýµÄ»Øµ÷ Host.RegisterExit((sender, e) => { XTrace.WriteLine($"ÊÕµ½Í˳öÐźÅ: {sender}"); }); ``` ## ÈÝÆ÷¼¯³É ### AddHostedService À©Õ¹·½·¨ ```csharp // ͨ¹ýÀàÐÍ×¢²á IObjectContainer AddHostedService<THostedService>() // ͨ¹ý¹¤³§×¢²á IObjectContainer AddHostedService<THostedService>( Func<IServiceProvider, THostedService> factory) ``` **ʾÀý**£º ```csharp var ioc = ObjectContainer.Current; // ×¢²áºǫ́·þÎñ ioc.AddHostedService<MyBackgroundService>(); ioc.AddHostedService<DataSyncService>(); // ʹÓù¤³§ ioc.AddHostedService(sp => { var config = sp.GetRequiredService<AppConfig>(); return new ConfigurableService(config); }); // ´´½¨Ö÷»ú²¢ÔËÐÐ var host = new Host(ioc.BuildServiceProvider()); host.Run(); ``` ## ʹÓó¡¾° ### 1. ¼òµ¥ºǫ́·þÎñ ```csharp class Program { static void Main() { var ioc = ObjectContainer.Current; ioc.AddHostedService<WorkerService>(); var host = new Host(ioc.BuildServiceProvider()); host.Run(); } } public class WorkerService : IHostedService { private Timer? _timer; public Task StartAsync(CancellationToken cancellationToken) { _timer = new Timer(DoWork, null, 0, 5000); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { _timer?.Dispose(); return Task.CompletedTask; } private void DoWork(Object? state) { XTrace.WriteLine($"¹¤×÷ÖÐ... {DateTime.Now}"); } } ``` ### 2. ¶à·þÎñЭ×÷ ```csharp class Program { static void Main() { var ioc = ObjectContainer.Current; // ×¢²á¹²ÏíÒÀÀµ ioc.AddSingleton<IMessageQueue, RedisMessageQueue>(); ioc.AddSingleton<ILogger, FileLogger>(); // ×¢²á¶à¸öºǫ́·þÎñ ioc.AddHostedService<MessageConsumerService>(); ioc.AddHostedService<HealthCheckService>(); ioc.AddHostedService<MetricsCollectorService>(); var host = new Host(ioc.BuildServiceProvider()); host.Run(); } } ``` ### 3. ¶¨Ê±ÈÎÎñ·þÎñ ```csharp public class ScheduledTaskService : IHostedService { private readonly ILogger _logger; private TimerX? _timer; public ScheduledTaskService(ILogger logger) { _logger = logger; } public Task StartAsync(CancellationToken cancellationToken) { // ÿÌìÁ賿2µãÖ´ÐÐ _timer = new TimerX(ExecuteTask, null, "0 0 2 * * *"); _logger.Info("¶¨Ê±ÈÎÎñ·þÎñÒÑÆô¶¯"); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { _timer?.Dispose(); _logger.Info("¶¨Ê±ÈÎÎñ·þÎñÒÑÍ£Ö¹"); return Task.CompletedTask; } private void ExecuteTask(Object? state) { _logger.Info("Ö´Ðж¨Ê±ÈÎÎñ..."); // ÈÎÎñÂß¼­ } } ``` ### 4. ´ø³¬Ê±µÄ²âÊÔÔËÐÐ ```csharp class Program { static async Task Main() { var ioc = ObjectContainer.Current; ioc.AddHostedService<TestService>(); var host = new Host(ioc.BuildServiceProvider()); host.MaxTime = 30_000; // 30Ãëºó×Ô¶¯Í£Ö¹ await host.RunAsync(); Console.WriteLine("²âÊÔÍê³É"); } } ``` ### 5. ÓÅÑÅÍ˳ö´¦Àí ```csharp public class GracefulService : IHostedService { private readonly List<Task> _runningTasks = new(); private CancellationTokenSource? _cts; public Task StartAsync(CancellationToken cancellationToken) { _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); // Æô¶¯¶à¸ö¹¤×÷ÈÎÎñ for (var i = 0; i < 5; i++) { _runningTasks.Add(WorkerLoop(i, _cts.Token)); } return Task.CompletedTask; } public async Task StopAsync(CancellationToken cancellationToken) { XTrace.WriteLine("ÊÕµ½Í£Ö¹Ðźţ¬µÈ´ýÈÎÎñÍê³É..."); // È¡Ïû¹¤×÷ÈÎÎñ _cts?.Cancel(); // µÈ´ýËùÓÐÈÎÎñÍê³É£¬×î¶àµÈ´ý10Ãë var timeout = Task.Delay(10_000, cancellationToken); var allTasks = Task.WhenAll(_runningTasks); await Task.WhenAny(allTasks, timeout); XTrace.WriteLine("ËùÓÐÈÎÎñÒÑÍ£Ö¹"); } private async Task WorkerLoop(Int32 id, CancellationToken token) { while (!token.IsCancellationRequested) { XTrace.WriteLine($"Worker {id} Ö´ÐÐÖÐ..."); await Task.Delay(1000, token).ConfigureAwait(false); } } } ``` ## Í˳öÐźŴ¦Àí Host ×Ô¶¯´¦ÀíÒÔÏÂÍ˳öÐźţº | ÐźŠ| ƽ̨ | ˵Ã÷ | |------|------|------| | Ctrl+C | ȫƽ̨ | ¿ØÖÆÌ¨ÖÐ¶Ï | | SIGINT | Linux/macOS | ÖжÏÐźŠ| | SIGTERM | Linux/macOS | ÖÕÖ¹Ðźţ¨Docker ĬÈÏ£© | | SIGQUIT | Linux/macOS | Í˳öÐźŠ| | ProcessExit | ȫƽ̨ | ½ø³ÌÍ˳öʼþ | **Docker ²¿Êð×¢Òâ**£º ```dockerfile # ʹÓà exec ÐÎʽ£¬È·±£ÐźÅÕýÈ·´«µÝ CMD ["dotnet", "MyApp.dll"] # »òÕßʹÓà tini ×÷Ϊ init ½ø³Ì ENTRYPOINT ["/sbin/tini", "--"] CMD ["dotnet", "MyApp.dll"] ``` ## ×î¼Ñʵ¼ù ### 1. ·þÎñÆô¶¯Ë³Ðò ·þÎñ°´×¢²á˳ÐòÆô¶¯£¬°´·´Ïò˳ÐòÍ£Ö¹£º ```csharp ioc.AddHostedService<DatabaseService>(); // ÏÈÆô¶¯£¬ºóÍ£Ö¹ ioc.AddHostedService<CacheService>(); // µÚ¶þ ioc.AddHostedService<ApiService>(); // ºóÆô¶¯£¬ÏÈÍ£Ö¹ ``` ### 2. Òì³£´¦Àí Æô¶¯Ê§°Üʱ»á×Ô¶¯»Ø¹öÒÑÆô¶¯µÄ·þÎñ£º ```csharp public class MyService : IHostedService { public async Task StartAsync(CancellationToken cancellationToken) { // Èç¹ûÅ׳öÒì³££¬ÒÑÆô¶¯µÄ·þÎñ»á±»×Ô¶¯Í£Ö¹ await InitializeAsync(); } public Task StopAsync(CancellationToken cancellationToken) { // È·±£Í£Ö¹Âß¼­²»Å׳öÒì³£ try { return CleanupAsync(); } catch (Exception ex) { XTrace.WriteException(ex); return Task.CompletedTask; } } } ``` ### 3. ×ÊÔ´ÊͷŠʵÏÖ `IDisposable` ½øÐжîÍâÇåÀí£º ```csharp public class ResourceService : IHostedService, IDisposable { private FileStream? _file; public Task StartAsync(CancellationToken cancellationToken) { _file = File.OpenWrite("data.log"); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } public void Dispose() { _file?.Dispose(); } } ``` ## Ïà¹ØÁ´½Ó - [¶ÔÏóÈÝÆ÷ ObjectContainer](/NewLife/X/Blob/master/Doc/object_container-¶ÔÏóÈÝÆ÷ObjectContainer.md) - [¸ß¼¶¶¨Ê±Æ÷ TimerX](/NewLife/X/Blob/master/Doc/timerx-¸ß¼¶¶¨Ê±Æ÷TimerX.md) - [ÈÕ־ϵͳ ILog](/NewLife/X/Blob/master/Doc/log-ÈÕÖ¾ILog.md)