Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 不进行上下文切换的跨AppDomain线程池_C#_.net_Clr_Threadpool_Appdomain - Fatal编程技术网

C# 不进行上下文切换的跨AppDomain线程池

C# 不进行上下文切换的跨AppDomain线程池,c#,.net,clr,threadpool,appdomain,C#,.net,Clr,Threadpool,Appdomain,我们的应用程序需要大量CPU,以尽可能快的速度处理数十亿个元组的数据。它使用多核,并很快向分布式云中移动 因此,我们的目标是尽可能高效地使用CPU。这个问题是关于如何保持高水平的性能,以允许在运行时动态加载/卸载插件 请理解,虽然跨AppDomains进行通信很容易,但没有一种“简单”的方式能够满足上述性能要求。因此,这个问题讨论了常见技术太慢的原因,进一步的需求,以及我们的想法要解决的具体问题 为了实现性能,应用程序被设计为通过“消息传递”在组件之间进行通信,这意味着我们有一个用户模式任务调度

我们的应用程序需要大量CPU,以尽可能快的速度处理数十亿个元组的数据。它使用多核,并很快向分布式云中移动

因此,我们的目标是尽可能高效地使用CPU。这个问题是关于如何保持高水平的性能,以允许在运行时动态加载/卸载插件

请理解,虽然跨AppDomains进行通信很容易,但没有一种“简单”的方式能够满足上述性能要求。因此,这个问题讨论了常见技术太慢的原因,进一步的需求,以及我们的想法要解决的具体问题

为了实现性能,应用程序被设计为通过“消息传递”在组件之间进行通信,这意味着我们有一个用户模式任务调度器来保持这些线程繁忙,而不会(除非必要)将任何时间片或上下文切换放弃到操作系统

在.NET中卸载DLL的唯一方法是通过AppDomains。但是,要保持上述高水平的性能,这意味着线程池(我们有自己的自行开发的线程池)必须能够在各种不同的AppDomain中执行任务

更具体地说,如果几十个AppDomain中的每一个都有单独的线程来竞争CPU,那么性能将非常糟糕。由于操作系统花费大量时间在线程之间切换上下文,CPU受限的工作中线程多于内核将降低性能

经过初步研究,我们自己的线程池似乎没有任何有效的方法可以以任何一种体面的性能进入其他AppDomain。即使方法的参数为零,远程处理或序列化的速度也不可能太慢

请注意,这与数据共享无关。我们不希望使用对不同AppDomain的线程调用来传递数据。相反,我们希望通过套接字和内存映射文件在AppDomain之间共享数据,以获得一流的性能,就像正确的进程间通信一样。因此,这个问题只涉及让线程跨应用程序域工作

下面关于Stackoverflow的链接已经有2年多的历史了,它提示利用CLR for.Net中的内置线程池,该线程池声明它跨越其他AppDomain来执行任务。MS文档还验证CLR线程池是否跨所有AppDomain运行

还是在阅读了文档之后,如何跨AppDomain使用内置线程池,同时在跨AppDomain时不允许任何上下文切换

因此,设计目标是如何旋转线程(每个核心一个),以频繁检查每个AppDomain中任务的“运行队列”,查看是否有工作要做,然后移动到下一个AppDomain?等等,循环通过每个AppDomains调度器?如何在不等待任何上下文切换开销或远程处理或编组的情况下执行此操作

当然,请注意,我们将有一些巧妙之处,将AppDomain分配给每个线程,以避免一级缓存未命中,从而避免硬件瓶颈


我们想知道的另一个想法是编写我们自己的定制CLR主机。看来,C++ API允许实现我们自己的线程池。有人知道这是否会考虑到上述功能吗?如果是这样,这是通过非托管代码实现的唯一方法吗

你有没有想过不要在appdomains中“拉”来工作,而是让appdomains推到一个集中的位置?(欢迎引擎)插件是否需要立即卸载?有可能在达到某个阈值后启动一个新的应用程序域吗?我假设您尝试使用AppDomain.DoCallback,但结果证明这会减慢速度?实际上,他们已经在拉和推数据了。否则,你的建议将如何解决这个问题还不清楚。斯奈尔,它们不需要立即卸载。大多数都会运行数天或数周,然后才决定是否需要停止、重新启动,甚至用新版本替换。