2016-04-26 13 views
2

私はEntity Framework 6.1.3を対象としたC#.NET4.5コンソールアプリケーションを作成しています。 次のように私は仕事のパラダイムの単位を使用しています:Entity Frameworkはマルチスレッドをサポートしていますか?

public class UnitOfWork : IUnitOfWork, IDisposable 
{ 
    private readonly DataContext _context; 
    private readonly List<object> _repositories = new List<object>(); 
    public UnitOfWork(DataContext context) 
    { 
     _context = context; 
     _context.Configuration.LazyLoadingEnabled = false; 
    } 

    public IRepository<T> GetRepository<T>() where T : class 
    { 
     //try to get existing repository 
     var repo = (IRepository<T>)_repositories.SingleOrDefault(r => r is IRepository<T>); 
     if (repo == null) 
     { 
      //if not found, create it and add to list 
      _repositories.Add(repo = new EntityRepository<T>(_context)); 
     } 
     return repo; 
    } 

    public int Commit() 
    { 
     return _context.SaveChanges(); 
    } 


    public bool AutoDetectChanges 
    { 
     get { return _context.Configuration.AutoDetectChangesEnabled; } 
     set { _context.Configuration.AutoDetectChangesEnabled = value; } 
    } 

そして、このように私のリポジトリ:

public class EntityRepository<T> : IRepository<T> where T: class 
    { 
     protected readonly DbContext Context; 
     protected readonly DbSet<T> DbSet; 
    public EntityRepository(DbContext context) 
    { 
     Context = context;    
     DbSet = Context.Set<T>(); 
    } 

    public IQueryable<T> All() 
    { 
     return DbSet; 
    } 
    ….. other functions…. 

    public virtual void Add(T entity) 
    {   
     DbEntityEntry dbEntityEntry = Context.Entry(entity); 
     if (dbEntityEntry.State != EntityState.Detached) 
     { 
      dbEntityEntry.State = EntityState.Added; 
     } 
     else 
     { 
      DbSet.Add(entity); 
     } 
    } 
    } 

を、私はこのようにこれらを呼び出す:

var rep = _uow.GetRepository<TableOfPies>(); 
rep.Add(Pie); 
_uow.Commit(); 

マイコンソールアプリケーションが複数あり各スレッドは、ある時点で、クラウドベースのSQL Serverデータベース内の同じテーブルに対して更新/編集/追加を行います。

ロックを使用して他のコードにスレッドセーフなコードを実装しましたが、エンティティをスレッドセーフにする方法がわかりません。私はオンライン見ているとエンティティとマルチスレッドについて多くを見つけることができませんでした

INNER EXCEPTION: New transaction is not allowed because there are other threads running in the session.

:今、私は次のエラーを取得します。 Entityはマルチスレッドアプリケーションをサポートしていないと聞いたことがありますが、それは信じられると聞いています。どんな指針も大変ありがとうございます。

+0

マルチスレッドでは、_CPU-bound_タスクのみが改善されることに注意してください。データベースタスクは一般的にI/Oバウンド(「クラウド」データベースの場合はそれ以上)であるため、マルチスレッド化はあまり役に立たないかもしれませんし、複数スレッドのオーバーヘッドが何らかの利益を上回る場合でも_ワースセンスかもしれません。 –

+0

@DStanleyこれは完全に真実ではありません。私はI/Oタスクで常にマルチスレッドを使用しており、大きなメリットがあります。利点は、1つのクエリへの返信を待っている間に、次のクエリを準備して送信できることです。もちろん、それは本当に複数のスレッドに依存しません。それはマルチタスキングによく似ていますが、しばしば同じように見えます。私は本当にそのための.NETの新しいタスクライブラリが好きです。私はマルチスレッドのようにコードを作成しますが、フレームワークは実際に使用するスレッドの数を処理します。 –

答えて

5

DataContext状態のドキュメント:

Any instance members are not guaranteed to be thread safe.

そして、それは私も経験してきたものです。私はあなたがやっていることをやろうとしましたが、スレッドセーフではないというアイデアをバックアップする奇妙なエラーが見られました。

各スレッドで新しいDataContextインスタンスを作成する必要があります。

+0

うわー。それは簡単な解決策です...私はSQLに戻る必要があると思った。スレッドごとに1つのDataContext。ニース。試してみます。 –

関連する問題