C# 基于EF的单例设计模式与异步方法
我有一个wpf应用程序,其中我使用EF作为ORM 我有许多异步调用的方法:C# 基于EF的单例设计模式与异步方法,c#,.net,wpf,entity-framework,uml,C#,.net,Wpf,Entity Framework,Uml,我有一个wpf应用程序,其中我使用EF作为ORM 我有许多异步调用的方法: public Task<double> GetSelectedOGCAvance2(int reference) { return Task.Factory.StartNew(() => { DataEntities _db = new DataEntities(); _d
public Task<double> GetSelectedOGCAvance2(int reference)
{
return Task.Factory.StartNew(() =>
{
DataEntities _db = new DataEntities();
_db.Configuration.LazyLoadingEnabled = false;
using (_db)
{
var dpcs = _db.ass_dpc_ogc.Where(x => x.ass_dpc_id_fk == reference).ToList();
return (Double)dpcs[0].ass_dpc_ogc_avance2.Value;
}
});
}
上面的方法是一个例子,所有使用的方法都与之类似
我希望将Singleton模式实现到DbContext _db,而不是在每个方法中创建和处理它
我想知道这是不是个好主意?如果存在另一种可以改进代码的方法,我愿意接受建议单例模式用于拒绝创建多个实例。作为这种模式的一个可容忍的缺点,它创建了一个全局变量。这就是你为它的使用付出的代价 你似乎是那些想要一个全局变量的人中的一员,已经读到全局变量是坏的tm,现在他们发现了单例模式,虽然他们不需要它的优点,但他们会很乐意为此付出代价,因为现在你有了一个拥有全局变量的借口:但这是一种模式 别说了。模式本身并不好。它们是解决问题的工具。你没有问题,所以不要应用随机工具来修复它 找到你的问题,然后再寻找模式。提示:在99%的情况下,单例并不能很好地解决您的问题。即使看起来是这样,我向您保证,使用单例生存期变量的依赖注入会更好
在您的情况下,向所有函数传递一个变量就足够了。单例模式用于拒绝创建多个实例。作为这种模式的一个可容忍的缺点,它创建了一个全局变量。这就是你为它的使用付出的代价 你似乎是那些想要一个全局变量的人中的一员,已经读到全局变量是坏的tm,现在他们发现了单例模式,虽然他们不需要它的优点,但他们会很乐意为此付出代价,因为现在你有了一个拥有全局变量的借口:但这是一种模式 别说了。模式本身并不好。它们是解决问题的工具。你没有问题,所以不要应用随机工具来修复它 找到你的问题,然后再寻找模式。提示:在99%的情况下,单例并不能很好地解决您的问题。即使看起来是这样,我向您保证,使用单例生存期变量的依赖注入会更好
在您的情况下,只需向所有函数传递一个变量就足够了。正如@nvoigt所提到的,单变量并不是一个好主意,您最好使用IoC来控制对象的生命周期 然而,如果你想写一本,Jon Skeet是一本很好的指南。他的第六个版本的通用版本可能如下所示:
public class Foo {}
public sealed class Singleton<T> where T : class, new()
{
private static readonly Lazy<T> lazy = new Lazy<T>(() => new T());
public static T Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
void Main()
{
Foo foo1 = Singleton<Foo>.Instance;
Foo foo2 = Singleton<Foo>.Instance;
if(foo1 == foo2)
{
Console.WriteLine("Foos are equal");
}
}
var container = new GalaSoft.MvvmLight.Ioc.SimpleIoc();
var foo = new Foo();
container.Register<Foo>(() => foo);
var foo1 = container.GetInstance<Foo>();
var foo2 = container.GetInstance<Foo>();
if(foo1 == foo2 && foo1 == foo)
{
Console.WriteLine("Foos are equal");
}
正如@nvoigt所提到的,单例很少是一个好主意,您最好使用IoC来控制对象的生命周期 然而,如果你想写一本,Jon Skeet是一本很好的指南。他的第六个版本的通用版本可能如下所示:
public class Foo {}
public sealed class Singleton<T> where T : class, new()
{
private static readonly Lazy<T> lazy = new Lazy<T>(() => new T());
public static T Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
void Main()
{
Foo foo1 = Singleton<Foo>.Instance;
Foo foo2 = Singleton<Foo>.Instance;
if(foo1 == foo2)
{
Console.WriteLine("Foos are equal");
}
}
var container = new GalaSoft.MvvmLight.Ioc.SimpleIoc();
var foo = new Foo();
container.Register<Foo>(() => foo);
var foo1 = container.GetInstance<Foo>();
var foo2 = container.GetInstance<Foo>();
if(foo1 == foo2 && foo1 == foo)
{
Console.WriteLine("Foos are equal");
}
在多个线程上重用dbcontext不是一个好主意。它可能不是线程安全的,如何启动事务等。。。任何改进这种方法的想法,我的意思是如何使DbContext线程安全不,您甚至不应该考虑它。它的设计寿命短,创建/删除成本低。它可以处理所有昂贵的事情,如连接池等。@peer但是在我的例子中,当我使用两个异步方法,并且每个方法都需要很多时间来执行时,我认为如果我添加一些其他方法,这将在将来产生一个问题。时间不是在创建和删除数据库上下文,而是在数据库查询中。如果查询的成本低于创建dbcontext的成本,那么异步执行就没有意义。如果您的logic/db查询非常昂贵,那么最好是找到一种优化它们的方法,而不是寻求微观优化,因为微观优化可能会在负载下导致错误或不期望的结果。在多个线程上重用dbcontext不是一个好主意。它可能不是线程安全的,如何启动事务等。。。任何改进这种方法的想法,我的意思是如何使DbContext线程安全不,您甚至不应该考虑它。它的设计寿命短,创建/删除成本低。它可以处理所有昂贵的事情,如连接池等。@peer但是在我的例子中,当我使用两个异步方法,并且每个方法都需要很多时间来执行时,我认为如果我添加一些其他方法,这将在将来产生一个问题。时间不是在创建和删除数据库上下文,而是在数据库查询中。如果查询的成本低于创建dbcontext的成本,那么异步执行就没有意义。如果您的logic/db查询非常昂贵,那么最好是找到一种优化它们的方法,而不是寻求可能导致错误或不希望的结果的微观优化
er load。在我的例子中,我如何使用IoC来控制DBContext的生存期?在我的例子中,我如何使用IoC来控制DBContext的生存期?在我的例子中,我如何使用IoC来控制DBContext的生存期?