C# 在应用程序域之间快速传递大量数据

C# 在应用程序域之间快速传递大量数据,c#,appdomain,C#,Appdomain,我有一个应用程序,用于将一个大型数据集(数百万条记录)从一个数据库导入另一个数据库,并在此过程中进行区分(即删除已删除的内容、更新内容等)。由于存在许多外键约束等,为了尝试加快应用程序的处理速度,它将整个目标数据库加载到内存中,然后尝试加载部分源数据库,并执行内存内比较,在运行时更新目标内存。最后,它将这些更改写回目标。数据库不一一匹配,因此一个数据库中的一个表可能是另一个数据库中的多个表,以此类推 所以我的问题是:目前运行这个过程需要几个小时(有时接近一天,具体取决于添加/更改的数据量),这使

我有一个应用程序,用于将一个大型数据集(数百万条记录)从一个数据库导入另一个数据库,并在此过程中进行区分(即删除已删除的内容、更新内容等)。由于存在许多外键约束等,为了尝试加快应用程序的处理速度,它将整个目标数据库加载到内存中,然后尝试加载部分源数据库,并执行内存内比较,在运行时更新目标内存。最后,它将这些更改写回目标。数据库不一一匹配,因此一个数据库中的一个表可能是另一个数据库中的多个表,以此类推

所以我的问题是:目前运行这个过程需要几个小时(有时接近一天,具体取决于添加/更改的数据量),这使得调试非常困难。从历史上看,当我们遇到错误时,我们会进行更改,然后重新运行应用程序,该应用程序必须再次将所有数据加载到内存中(需要相当长的时间),然后运行导入过程,直到找到我们所处的部分,然后我们交叉手指,希望更改能够奏效。这不好玩:(

为了加快调试过程,我正在做一个架构更改,将导入代码移动到一个单独的dll中,加载到一个单独的appdomain中,这样我们就可以卸载它,进行更改,然后重新加载它,并尝试再次运行导入的一部分,从我们停止的地方开始,看看我们是否得到了更好的结果。我认为我是当我提出这个计划时,他是个天才:)但它有一个问题。我要么必须将目标数据库中的所有数据加载到第二个appdomain中,然后在卸载之前,使用[Serializable]处理将所有数据复制到第一个appdomain中(卸载和重新加载dll时这非常慢),要么将数据加载到主appdomain中,并使用MarshallByRefObject在第二个appdomain中引用它(事实证明,这似乎使整个过程变得缓慢)

所以我的问题是:我怎样才能快速做到这一点?比如,最多一分钟!我希望只复制数据,就好像它只是通过引用传递的一样,而不必实际进行完整复制。

我想知道是否有更好的方法来实现这一点,以便更好地在两者之间共享数据,或者至少在两者之间快速传递数据。我搜索并发现了一些建议使用数据库的东西(我们正在将数据加载到内存中以避免数据库)或者只是说使用MarshallByRefObject。我很想做一些简单的事情,但它还没有真正起作用

我在某个地方看到,加载C++ DLL或非托管DLL会导致它忽略应用程序域,并会带来一些问题。无论如何,我可以使用它来发挥我的优势,即,加载一个非托管DLL,它为我或其他东西保存我的列表,并用它欺骗我的应用程序,使两个AppDead使用相同的内存,使LIS当我通过卸载应用程序域来卸载另一个dll时,它只是在原地不动


我希望这是有意义的。这是我在这里的第一个问题,所以如果我做得很糟糕,一定要帮我。这让我沮丧了几天。

应用程序域方法是一种很好的分离方法,目的是只加载/卸载应用程序的一部分。不幸的是,正如您所发现的,在两个应用程序域之间交换数据是错误的ot简单/快速。这就像两个不同的系统进程尝试通信一样,总是比同一进程通信慢。因此,方法是使用尽可能快的进程间通信机制。跳过WCF,因为它不需要额外开销。使用它可以非常快地流式传输数据。我曾经使用过它这样做会有很好的效果。要想更快,你可以尝试
MemoryMappedFile
(),但这更难实现。从命名管道开始,如果命名管道太慢,就使用内存映射文件

即使使用快速发送方式,您也可能遇到另一个瓶颈-数据序列化。对于大量数据,标准序列化(甚至二进制)速度非常慢。您可能想看看谷歌的

关于AppDomain,有一点要小心——任何一个应用程序域中的未捕获异常都会导致整个过程失败。不幸的是,它们并没有那么分开


另一方面,我不知道你的应用程序做了什么,但数百万条记录似乎并没有那么多。也许有优化的余地?

你没有说它是否是SQL Server,但你有没有考虑过使用它来实现这一点?显然有一些方法可以加快大数据的处理速度。

有趣的问题。但是,代码不是很简单吗获取某种类型的测试覆盖率(即使在高级别)?看在上帝的份上,调试时你不应该等那么久。我完全赞成尽可能地加快速度,提醒你,但一旦出现问题,你就必须浪费大量宝贵的时间,这一事实应该会让人想起。不过,我很好奇实际的答案是什么:)