C#服务中同一类内多无限循环任务并行运行的替代方案
解决C#服务应用中两个无限循环任务并行运行的问题
你的问题很典型——同步调用无限循环的方法会直接阻塞主线程,导致后续的方法根本没机会执行。下面给你几个实用的实现方案,都是生产环境里常用的:
方案1:手动创建独立线程(最直接的传统方式)
你可以把A()和B()分别放到两个独立的Thread实例中启动,这样它们就能并行执行了。记得设置线程为后台线程(IsBackground = true),这样当主线程退出时,这些后台线程会自动终止,避免程序挂起。
using System.Threading; class Program { static void Main() { // 为A()创建后台线程 var threadA = new Thread(App.A) { IsBackground = true }; // 为B()创建后台线程 var threadB = new Thread(App.B) { IsBackground = true }; // 启动两个线程 threadA.Start(); threadB.Start(); // 保持主线程存活,否则程序会直接退出 Console.WriteLine("服务已启动,按任意键退出..."); Console.ReadKey(); } } static class App { public static void A() { while (true) { Console.WriteLine("执行A任务逻辑..."); Thread.Sleep(60000); // 休眠60秒 } } public static void B() { while (true) { Console.WriteLine("执行B任务逻辑..."); Thread.Sleep(1000); // 休眠1秒 } } }
方案2:使用Task.Run(现代TPL并行方式)
基于Task Parallel Library(TPL)的Task.Run是更推荐的现代写法,它会利用线程池来管理线程,比手动创建线程更高效,也更易维护。
using System.Threading.Tasks; using System.Threading; class Program { static async Task Main() { // 将A()和B()包装为后台任务 var taskA = Task.Run(App.A); var taskB = Task.Run(App.B); // 保持主线程存活,否则程序会直接退出 Console.WriteLine("服务已启动,按任意键退出..."); Console.ReadKey(); } } static class App { public static void A() { while (true) { Console.WriteLine("执行A任务逻辑..."); Thread.Sleep(60000); } } public static void B() { while (true) { Console.WriteLine("执行B任务逻辑..."); Thread.Sleep(1000); } } }
如果需要优雅地停止任务,建议引入CancellationToken,这样可以在需要时终止无限循环,而不是强制杀死线程。比如修改方法接受取消令牌:
public static void A(CancellationToken token) { while (!token.IsCancellationRequested) { Console.WriteLine("执行A任务逻辑..."); Thread.Sleep(60000); } }
然后在Main里创建CancellationTokenSource,传递令牌给任务,退出时调用Cancel()即可。
方案3:使用Worker Service(适合长期运行的后台服务)
如果你的应用是.NET Core/.NET 5+的后台服务项目(比如用Worker Service模板创建的),可以把两个任务封装为BackgroundService,让框架来管理它们的生命周期,这是最适合服务应用的方案。
首先创建两个托管服务:
using Microsoft.Extensions.Hosting; using System.Threading; using System.Threading.Tasks; public class TaskAWorker : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { await Task.Delay(60000, stoppingToken); // 用Task.Delay替代Thread.Sleep,支持取消 Console.WriteLine("执行A任务逻辑..."); } } } public class TaskBWorker : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { await Task.Delay(1000, stoppingToken); Console.WriteLine("执行B任务逻辑..."); } } }
然后在Program.cs里注册服务:
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; IHost host = Host.CreateDefaultBuilder(args) .ConfigureServices(services => { services.AddHostedService<TaskAWorker>(); services.AddHostedService<TaskBWorker>(); }) .Build(); await host.RunAsync();
这种方式的好处是框架会自动处理服务的启动、停止、异常处理,非常适合长期运行的服务应用。
内容的提问来源于stack exchange,提问作者Prajwal Bhat
相关产品推荐
相关产品推荐

