2012-12-05 21 views
6

Çerçevemizin paralellikleri üzerinde çalışırken, neden hayal edemediğim garip bir durumla karşılaştım! Durumu açıklamak için durumu basitleştirdim.Yerel bir değişkenin null olarak değiştirilmesi, başka bir iş parçacığı aracılığıyla, bu nasıl mümkün olabilir

foreach(var person in personList) 
{ 
    if (person.Name == "Mehran") 
     break; 
} 

personList birden çok iş parçacığı arasında paylaşılır: bu kodu düşünün. personnull olmak ve ben person.Name için NullReferenceException olsun için Hangi durumlarda

bu mümkün mü?

bildiğim gibi, kişi burada yerel bir değişken olarak kabul edilir ve biz foreach bloğun içine almak, bu yüzden başarılı personList iterated varsa, bu nedenle person hiçbir şekilde ya da herhangi bir paralel senaryoda boş olmamalıdır. personList başka bir iş parçacığı tarafından değiştirildi veya başvurulan person tanzim bile

, person değişken bir değere sahip olmalıdır. Kimse, person'un başvurulduğu yere erişme hakkına sahip olmadığı için.

Durumu açıklayan herhangi bir senaryo mu? Bildiğim kadarıyla

cevap

11

, kişi burada yerel bir değişken olarak kabul edilir ve biz foreach bloğunun içine almak, bu yüzden başarılı personList iterated, bu yüzden kişi hiç bir şekilde ya da herhangi bir paralel senaryoda boş olmamalı eğer .

Sadece personList üzerinden yineleme yaptığınız için, hiç boş değer içermediği anlamına gelmez. Örneğin:

List<Person> personList = new List<Person>(); 
personList.Add(null); 

foreach (var person in personList) 
{ 
    // Here, person will be null 
} 

(şey liste değiştiriyorsa, ayrıca, başın genellikle konum --iplik güvenli onlar değiliz yazarların karşısında - ama ihtiyaçlarını sanmıyorum sorunun bir parçası olun.)

+0

Wooops! listeler null kabul edebilir! Paralel durumlar, gerekenden daha karmaşık düşünmemi sağladı! Çok teşekkürler Jon. – mehrandvd

+0

Yep, Paralel durumlarda liste değiştirme sıkıntılarını biliyorum. Basit ve hızlı cevabınızın çözeceğini düşünüyorum. Listedeki olası boş değerleri kontrol edeceğim. – mehrandvd

3

Değişken değiştirilmedi. iş parçacığı güvenli değil foreach yapısını uygulamak için kullanılan yineleyici:

List<T>.IEnumerable<T>.GetEnumerator() belgelenmesi itibaren here bulundu:

Bir Numaralandırıcı toplama değişmeden kalır sürece geçerli kalır. Koleksiyonda, ekleme, değiştirme veya silme gibi değişiklikler yapılırsa, numaralandırıcı geri alınamaz bir şekilde geçersizleştirilir ve davranışı tanımsızdır.

Sayım, koleksiyona özel erişim hakkına sahip değildir; Bu nedenle, bir koleksiyonda numaralandırmak içsel olarak bir diş güvenli prosedür değildir. Numaralandırma sırasında iplik güvenliğini sağlamak için, tüm numaralandırma sırasında koleksiyonu kilitleyebilirsiniz. Koleksiyona, okuma ve yazma için çoklu iş parçacıklarının erişmesine izin vermek için kendi eşitlemenizi uygulamanız gerekir.

System.Collections.Generic ad alanındaki koleksiyonların varsayılan uygulamaları senkronize edilmez.

Listelerde başka bir iş parçacığının değişiklik olasılığının bulunması olasılığına karşı listeyi her zaman yineleyin.

İlgili konular