You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:36:14