5

ile birden fazla iş parçacığı üzerinde bağımlılıkları kullanma IoC konteyneri olarak Simple Injector kullanıyorum. SimpleInjector Maalesef (ve tabii ki!) this simple technique to handle mixed life style for Per Thread and Per Web RequestParallel.ForEach

container.RegisterPerWebRequest<IWebRepository, Repository>(); 
container.RegisterLifetimeScope<IThreadRepository, Repository>(); 
container.Register<IRepository>(container.GetInstance<Repository>()); 

// Register as hybrid PerWebRequest/PerLifetimeScope. 
container.Register<Repository>(() => 
{ 
    Repository repository; 
    if (HttpContext.Current != null) 
     repository = (Repository)container.GetInstance<IWebRepository>(); 
    else 
     repository = (Repository)container.GetInstance<IThreadRepository>(); 

    return repository; 
}); 

kullanır, başka yerde benim UnitOfWork sınıfta ben Parallel.ForEach kullanabilir ve yalnızca paralel Depo sınıfın birden çok örneği içine aramaya çalıştığınızda bu bana bir sorunu veriyor ilk iplik Şimdi ben muhtemelen imkansız ya da aptal bir şey soruyorum görebilirsiniz soruyu yazmayı bitirdiğinize HttpContext.Current

using (TransactionScope scope = new TransactionScope()) 
{ 
    Parallel.ForEach(new List<IRepository>() { _repository1, _repository2 ... }, 
     (repository) => 
     { 
      repository.Commit(); 
     }); 
    scope.Complete(); 
} 

bir değer bulur ... ama her neyse. .. bu yapılabilir mi? Birden fazla iç iş parçacığına bir istek/iş parçacığı kaydı yapılabilir mi?

cevap

7

Bağımlılık enjeksiyonunda, nesnelerin kullanım ömrü ile ilgili bilgileri merkezileştirmeye çalışırsınız. Bu merkezi yer, Composition Root olarak adlandırılır. Bağımlılıkları bir iş parçacığından diğerine aktarmaya başladığınızda, kodun bu bölümleri bu bağımlılıkları geçmenin güvenli olup olmadığını bilmek zorundadır. Mesela, bağımlılıklar iplik güvenli midir? Bu bağımlılıklar bu yeni bağlamda çalışabilir mi (örneğin bir HTTP veya WCF talebi dışında)? Bu, birçok durumda analiz etmek için önemsiz olabilir, ancak bu bağımlılıkları başka uygulamalarla değiştirmenizi önler, çünkü şu anda kodunuzda bunun gerçekleştiği yer olduğunu ve hangi bağımlılıkların geçtiğini bilmeniz gerektiğini unutmayın. Bu bilgiyi tekrar merkezileştiriyorsunuz, DI konfigürasyonunuzun doğruluğu konusunda daha da zorlaştırıyorsunuz ve konteynerinizi doğrudan (en iyisi) başarısız kılacak şekilde ya da en zorlu koşullarda yarış hatalarını ayıklamayacak şekilde yanlış yapılandırmanızı kolaylaştırıyorsunuz.).

Her yeni başlatılan iş parçacığına, kapsayıcıyı sorarak yeni bir nesne grafiği oluşturmasına izin vermek en güvenli yöntemdir. Bağımlılıklardan (yani: konteyner tarafından yönetilen ve enjekte edilen örnekler) bir iş parçacığından diğerine geçmeyin. Sizin durumunuzda, diğer konulara aktarılamayacak gibi görünmediğinden, depolarınız http bağlamıyla bir ilişki içerisindeydiklerinden, sorunlara bile çarpar gibi görünüyorsunuz. Bu durumda oldukça kolaydır: Bunu yapmayın ;-)

Bu, herhangi bir şekilde performansı artırmak için çok iş parçacığı yapamayacağınız anlamına gelmez. Bununla birlikte, bu işlemin bağımlılıkları bir iş parçacığından iş parçacığına veya bunu yaptığınızda değiştirmemesine dikkat edin; Bu kodun (sizin durumunuzda Parallel.ForEach) uygulamanızın Bileşim Kökünün içinde bulunduğundan emin olun, çünkü bu işlemin yürütülmesinin güvenli olup olmadığını bilmesi gereken tek yer burasıdır. Ancak, özel durumunuzda, birden fazla iş parçacığı üzerinde işlem yaptığınız konusunda oldukça korkutucu buluyorum. Bu iş biriminin taahhüdü atomik olmamalı mı? Farklı iş parçacıklarında depo yüklerini çalıştırdığınızda bu işlemin hala atomik olduğundan emin misiniz? İşlemlerden biri başarısız olduğunda ve diğerleri başarılı olduğunda ne olur? Zaten başarılı olan işlemleri nasıl geri yüklersiniz? Bu sorunları çözebildiğinizi (ve zaten sahip olabileceğinizi) düşünüyorum, ancak bu tür bir çözüm sisteme çok fazla karmaşıklık katar. Performans iyileştirmesinin, sisteme eklediğiniz ek karmaşıklığı gerçekten telafi edip etmediğini ciddi olarak sormalısınız.

Çoklu iş parçacıklı uygulamalarda bağımlılık enjeksiyonuyla çalışma hakkında daha fazla bilgi edinebilirsiniz here.