2017-12-08 5 views
0

インポートファイルのマルチスレッドバックグラウンドジョブを実装する必要があります。 バックグラウンドジョブ(Hangfire)で実装しました。しかし、もし私が非常に遅くなる1つのスレッドを使用します。 関数は次のようになります。要求ごとのDbContext aspboilerplate

私は非トランザクション単位を使用して、すぐにdbへの変更を保存します。

var contactFound = await _contactRepository.FirstOrDefaultAsync(x => x.Email.ToLower() == contact.Email.ToLower()); 

      if (contactFound != null) 
      { 
       await _bjInfoManager.AddLog(args.JobId, "Found duplicated email: " + contact.Email); 

      } 
      else 
      { 
       contact.ContactListId = args.ContactListId; 
       contact.Email = contact.Email.ToLower(); 

       await _contactRepository.InsertAsync(contact); 

       //Save changes in db 
       await CurrentUnitOfWork.SaveChangesAsync(); 
      } 

これをProducer-Consumer Dataflow Patternで使用しようとすると問題が発生します。私は例外をスローします "前の非同期操作が完了する前に、このコンテキストで2番目の操作が開始されました。"

質問は、このメソッド内で分離されたDbContextを作成する方法です。 私を助けてください。

答えて

0

トランザクションはマルチスレッドであってはなりません。 UOWで新しいタスク/スレッドを作成する場合は、usingブロックでIUnitOfWork.Begin(TransactionScopeOption.RequiresNew)を使用して別のUOWを作成できます。

はリンク

https://github.com/aspnetboilerplate/aspnetboilerplate/issues/619

  • Does Entity Framework support Multi-Threading?は、Microsoft SQL Serverを使用している場合を参照してください、私はあなたが一括挿入を使用することをお勧めします。エンティティフレームワークよりも高速です。

    https://docs.microsoft.com/en-us/sql/t-sql/statements/bulk-insert-transact-sql

  • +0

    はい。私は答えを得る前に把握する。感謝。しかし、多くの問題がありました。私はこの方法でこのフィールドへのインデックスを作成することはできません電子メールフィールドのMaxLengthを追加することを忘れました。しかし流暢なAPIはそれについて何も言わなかった。これらのことはテーブルがそれほど大きくなくても非常に検索が遅くなります。フィールドの長さを制限するためのフィールドのデータ注釈を作成した後、インデックスが作成され、すべての作業が高速に開始されます。もう一つは、私はメソッドのいずれかを使用しているdbのチェックメソッドが存在する、それはより速くfirstOfDefaultメソッドを動作します。 – grinay

    +0

    あなたが言及した内容は既に問題として提出されています... https://github.com/aspnetboilerplate/aspnetboilerplate/issues/2762 –

    +0

    私の回答が更新されました(SQLの一括挿入が追加されました) –

    関連する問題