1

让我描述一下我目前拥有的问题和解决方案,也许您可​​以帮助我了解为什么这是一个坏主意(假设是)以及我可以做些什么来使它成为一个更好的系统。

现在我有 600 个“开膛手”来解析文件并将它们撕成 csv 或其他格式。裂土器都实现了一个通用接口和基类。当作业根据该作业的配置排队时,使用反射调用特定的 ripper。

            foreach (var stream in streams)
            {
                try
                {
                    // load it
                    Assembly asm = Assembly.LoadFile(Path.Combine(stream.RipperPath, stream.RipperFileName), new Evidence());
                    if (asm == null)
                    {
                        MessageBox.Show(String.Format("Invalid Interface ripper loaded.\n{0}", Path.Combine(stream.RipperPath, stream.RipperFileName)));
                        return;
                    }

                    foreach (Type objType in asm.GetTypes())
                    {
                        if (!objType.IsPublic)
                            continue;

                        // make sure the type isn't Abstract
                        if (((objType.Attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract))
                            continue;

                        // IRipper is the interface that all of the Rippers must implement to be loaded
                        Type objInterface = objType.GetInterface("IRipper", true);
                        if (objInterface == null)
                            continue;

                        try
                        {
                            var iri = (IRipper)Activator.CreateInstance(objType);

                            // Rippers must register with their hosts
                            iri.Host = this;
                            iri.OnStart += RipperStart;
                            iri.OnComplete += RipperComplete;
                            iri.OnProgressChanged += RipperStatusUpdate;
                            iri.dataStream = stream;
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(String.Format("Error loading interface: {0}\n{1}", Path.Combine(stream.RipperPath, stream.RipperFileName), ex.Message));
                }
            } 

所有开膛手都实现了一个名为“Rip()”的函数,接口将它们收缩到该函数。

使用当前代码,我能看到的唯一问题是在加载 600 个程序集后(因为它们是在需要时加载的),如果它们在使用后没有被卸载,它会开始变得有点慢。

你有什么建议?

4

2 回答 2

1

您实际上有 600 个不同的裂土器,还是 600 个流和一些较少数量的裂土器?您真的需要每个开膛手都在自己的组装中吗?如果您可以将裂土器捆绑在一起,那么您可以拥有更少的组件。如果您的流详细信息包含类型名称以及可执行文件,则您可能有多个 ripper,并且您无需查看它们的程序集 - 只需调用Assembly.GetType.

请注意,我不知道每个程序集实际上有多少开销 - 我希望 600 个程序集会占用相当多的内存,但不会对性能产生太大影响。

总体方法似乎是合理的,尽管您可能还想查看托管可扩展性框架 (MEF) - 对于您的情况来说,这可能有点矫枉过正,但值得一看。我要做的另一件事是从“处理流”代码中排除“获取开膛手”:)

于 2009-03-16T17:19:29.683 回答
0

您可能想看看System.Addin的东西。加载项似乎加载到它们自己的应用程序域中,这使得在不再需要它们时可以干净地卸载它们。

于 2009-03-16T17:26:50.477 回答