Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.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# 哪种方法可以从动态加载程序集的帮助器类中获得更好的结果_C#_.net_Design Patterns_Architecture - Fatal编程技术网

C# 哪种方法可以从动态加载程序集的帮助器类中获得更好的结果

C# 哪种方法可以从动态加载程序集的帮助器类中获得更好的结果,c#,.net,design-patterns,architecture,C#,.net,Design Patterns,Architecture,我正在为企业解决方案编写一个数据适配器 为了使其可扩展,我将其设计为: 只有一个接口定义所有数据方法的签名 这个接口在各种低级适配器中实现,方法在这些适配器中实现,这些适配器像SqlAdapter、OracleAdapter、MySqlAdapter、XmlAdapter等。它们在2MB左右不是很大 我已经创建了一个Facade层,它在运行时使用configuration和底层适配器调用bind,并调用它的方法 这个外观在使用者之间共享,他们可以使用它调用方法,而不需要知道底层适配器 为了创建一

我正在为企业解决方案编写一个数据适配器

为了使其可扩展,我将其设计为:

  • 只有一个接口定义所有数据方法的签名
  • 这个接口在各种低级适配器中实现,方法在这些适配器中实现,这些适配器像SqlAdapter、OracleAdapter、MySqlAdapter、XmlAdapter等。它们在2MB左右不是很大
  • 我已经创建了一个Facade层,它在运行时使用configuration和底层适配器调用bind,并调用它的方法
  • 这个外观在使用者之间共享,他们可以使用它调用方法,而不需要知道底层适配器
  • 为了创建一个门面,我必须创建一个单吨的门面
  • 为了使其具有可扩展性,我采用了以下方法

  • 将单吨模式更改为基于多实例的模式(工厂模式),使实例数量可配置(对象池)。使用异步(使用异步等待)执行底层方法

  • 仅使用单实例,但使用信号量来处理并发请求的数量。使用连接池异步执行底层方法(使用async await),以便对底层方法的异步调用可以使用到数据库的多个连接

  • 问题: 1) 如果我选择第一种创建多个实例的方法,它会更快吗?加载底层适配器不会花费更多的时间,因此会比第二种方法慢吗?如果我克隆对象呢

    2) 如果我选择第二种方法,它会更快吗?由于单吨对象只中继请求和响应,所以后台的所有工作都是异步的

    考虑到对象重新加载,哪种方法在性能方面更好?或者还有其他好方法吗?
    假设每秒向服务器发送1000个请求。

    我将通过一个静态类包装对工厂的调用,该类可能是“FactoryInitializer”,它有一个接受适配器类型的通用方法,例如:

    public interface IDataAdapter
    {
        //Your methods
    }
    
    internal class SqlAdapter : IDataAdapter
    {
        //This is your concrete class where a specific adapter related stuff goes
        //You can create more of these concrete types as separate classes.
    }
    
    internal class BaseFactory
    {
        public virtual IDataAdapter GetDataAdapter()
        {
            return null;
        }
    }
    
    internal class SqlFactory : BaseFactory
    {
        public override IDataAdapter GetDataAdapter()
        {
            return new SqlFactory();
        }
    }
    
    internal static class FactoryInitializer
    {
        public static IDataAdapter LoadAdapterOf<T>() where T : BaseFactory, new()
        {
            var factory = new T();
            return factory.GetDataAdapter();
        }
    }
    
    公共接口适配器
    {
    //你的方法
    }
    内部类SqlAdapter:IDataAdapter
    {
    //这是一个具体的类,其中包含与适配器相关的特定内容
    //您可以创建更多这些具体类型作为单独的类。
    }
    内部类基工厂
    {
    公共虚拟IDataAdapter GetDataAdapter()
    {
    返回null;
    }
    }
    内部类SqlFactory:BaseFactory
    {
    公共重写IDataAdapter GetDataAdapter()
    {
    返回新的SqlFactory();
    }
    }
    内部静态类FactoryInitializer
    {
    公共静态IDataAdapter LoadAdapterOf(),其中T:BaseFactory,new()
    {
    var factory=newt();
    返回factory.GetDataAdapter();
    }
    }
    
    然后将其用作:

    var sqlAdapter = FactoryInitializer.LoadAdapterOf<SqlFactory>();
    
    var sqlAdapter=FactoryInitializer.LoadAdapterOf();
    
    为了更快、更可预测的实例化,应该预加载包含适配器实现的所有程序集。这是相当昂贵的操作。在此之后,您基本上有三个选择:

  • 重用适配器实例。对每种适配器类型使用池。如果适配器占用大量内存,并且频繁分配新实例,则此选项更可取,因为它会很快将堆分割成碎片
  • 为每个请求创建适配器的新实例。如果适配器具有某些内部状态,但内存占用相对较小,则此选项更可取。这些适配器将是第0代垃圾收集的一个很好的候选者,在.NET4.5中,第0代垃圾收集速度更快,甚至更快
  • 重用适配器实例。根本没有合用。只有在适配器完全没有任何状态的情况下,才可以使用此选项。这意味着没有竞争条件和同步

  • UPD:如果您选择第一个选项,并且将有太多和/或太大的适配器故障太长时间的内存问题,那么您可能需要考虑从“实时”处理模型切换到延迟处理。创建一个请求队列,实时推送请求,并使用某种调度器批量处理它们。

    您考虑过工厂设计模式吗???@AzharKhorasany我已经添加了更多细节为什么是匿名否定点?我认为您的瓶颈将与服务器通信本身有关,C#对象的实例化/单例访问不适用。@ChrisSinclair您的意思是任何一种方法都可以,两种模型都可以一次处理1000个请求,结果率更高?程序集不太大,
    LoadFrom
    不会重新加载已加载的程序集。但在预热阶段预加载程序集和预分配对象(如有必要)将使您免于在请求处理阶段遇到棘手的问题。