gpt4 book ai didi

c# - 如何扩展具有 50000 个同时任务的应用程序

转载 作者:行者123 更新时间:2023-12-03 12:48:30 25 4
gpt4 key购买 nike

我正在开发一个需要能够同时运行(例如)50,000 个任务的项目。每个任务将以某种频率(比如 5 分钟)运行,并且将是 url ping 或 HTTP GET 请求。我最初的计划是为每个任务创建线程。我进行了基本测试,看看在可用系统资源的情况下这是否可行。我将以下代码作为控制台应用程序运行:

public class Program
{
public static void Test1()
{
Thread.Sleep(1000000);
}

public static void Main(string[] args)
{
for(int i = 0; i < 50000; i++)
{
Thread t = new Thread(new ThreadStart(Test1));
t.Start();
Console.WriteLine(i);
}
}
}
不幸的是,虽然它开始非常快,但在 2000 线程标记处,性能大大下降。到 5000 时,我的计数速度比程序创建线程的速度还快。这使得达到 50000 似乎不太可能。我在正确的轨道上还是应该尝试其他方法?谢谢

最佳答案

很多人认为你需要生成 n 线程如果你想处理 n 并行任务。大多数情况下,计算机都在等待 I/O,例如网络流量、磁盘访问、GPU 计算的内存传输、硬件设备完成操作等。
鉴于这一见解,我们可以看到为给定硬件平台并行处理尽可能多的任务的可行解决方案是将工作流水线化:将工作放入队列中并使用尽可能多的线程对其进行处理。通常,这意味着每个虚拟处理器有 1-2 个线程。
在 C# 中,我们可以使用任务并行库 (TPL) 来完成此任务:

    class Program
{
static Task RunAsync(int x)
{
return Task.Delay(10000);
}

static async Task Main(string[] args)
{
var tasks = Enumerable.Range(0, 50000).Select(x => RunAsync());

Console.WriteLine("Waiting for tasks to complete...");

await Task.WhenAll(tasks);

Console.WriteLine("Done");
}
}
这会将 50000 个工作项排队,并等待所有 50000 个任务完成。这些任务只在需要的线程上执行。在幕后,任务调度程序检查工作池并拥有线程 偷工当他们需要执行任务时从队列中取出。
其他注意事项
对于较大的上限 (n=50000),您应该意识到内存压力、垃圾收集器事件和其他与任务相关的开销。您应该考虑以下几点:
  • 考虑使用 值任务 最小化分配,尤其是同步操作
  • 使用配置等待(假)尽可能减少上下文切换
  • 使用 CancellationTokenSource 取消 token 提前取消请求(例如超时)
  • 遵循最佳实践
  • 尽可能避免在循环内等待
  • 避免过于频繁地查询任务以完成
  • 避免访问 任务 .Result 在任务完成之前防止阻塞
  • 适本地使用同步原语(互斥体、信号量、条件信号、同步锁等)避免死锁
  • 避免频繁使用任务运行创建任务以避免耗尽默认任务调度程序可用的线程池(此方法通常保留用于计算密集型任务)

  • 关于c# - 如何扩展具有 50000 个同时任务的应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63232123/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com