2011-01-28 17 views
10

DateTime gibi uçucu DateTime kullanımı çekişme olmadanuçucu olarak ilan edilemez, bu hak ?: olduğunu

 private DateTime _time; 
     public DateTime Time 
     { 
      get 
      { 
       Thread.MemoryBarrier(); 
       return _time; 
      } 
      set 
      { 
       _time = value; 
       Thread.MemoryBarrier(); 
      } 
     } 
mülkiyet farklı parçacığı erişilebilir olamayacağını

, bu yüzden her zaman en son sürümünü almak sağlamak istiyoruz, (kilit).

DÜZENLEME:

  • Ben zor oluşturmak öğeleri, her biri bu öğe oluşturulduğunda belirten CreationTime adında bir DateTime özelliğine sahiptir bir koleksiyona sahip. DateTime.UtcNow için başlatıldı.
  • Her öğeye erişildiğinde, bu özellik DateTime.UtcNow olarak güncelleştirilir.
  • İş parçacığı, öğeyi sildiğinde (DateTime.UtcNow + 1 saat)> item.CreationTime öğesinin doğru olup olmadığını denetleyen bir iş parçacığında zamanında işleyen bir iş parçacığı vardır.

ben "silme parçacığı" koleksiyonu içine girdiğinde, tüm öğeler en son "son erişim" Üzerinde DateTime sahip olmasını sağlamak istiyoruz, bu yüzden bir önbellek düzenlenen sırf tekrar öğesi oluşturmak önleyebilirsiniz Birkaç milisaniye değeri: D

Şimdiden teşekkürler.

+0

Yapmaya çalıştığınız şeyin mantıklı olup olmadığından emin değilsiniz. En son sürümü nasıl tanımlarsınız? – CodesInChaos

+0

Yayını güncelledim – vtortola

+1

Belirli bir zaman diliminden daha eski kullanılmayan nesneleri kaldırmayı önleyen bir önbellek uyguladığınıza göre, 'InterlockedExchange' çözümünün buraya gitmenin bir yolu olduğunu düşünüyorum. –

cevap

12

Kesinlikle.

Başka bir seçeneğiniz var. Saati bir Int64 onay sayısı olarak saklayın ve ayarlamak için InterlockedExchange kullanın. Konular daha sonra Int64 yapıcı kullanarak kendi DateTime yapılarını oluşturarak hiçbir çekişme ve kilitleme yapamazlar.

DÜZENLEME: Daha fazla bilgiye sağladık göz önüne alındığında

, bu bir örnek sunmak amacıyla artık daha kolaydır.

public class Cache 
{ 
    class CacheEntry 
    { 
     private Int64 m_Touched; 

     public CacheEntry() 
     { 
      Touch(); 
     } 

     public void Touch() 
     { 
      System.Threading.Interlocked.Exchange(ref m_Touched, DateTime.Now.Ticks); 
     } 

     public DateTime Touched 
     { 
      get 
      { 
       return new DateTime(Interlocked.Read(ref m_Touched)); 
      } 
     } 
    } // eo class CacheEntry 
} // eo class Cache 
+3

Sadece ham kene saklamak yerine 'ToBinary' /' FromBinary' kullanmak daha iyidir, böylece 'DateTimeKind' de korunur. (Her ne kadar, OP'nin muhtemelen fazladan akıllı olmaya çalışmak yerine sadece bir 'kilit 've bir' DateTime 'kullanması gerektiğini iddia etsem de.) – LukeH

+2

Mümkün olsa da, bu önerilerin ikisi de çok fazla gereksiz olabilir ilgili dönüşümler. Bu, elbette, DateTime değerinin kaç tüketiciye sahip olduğuna bağlıdır. –

+2

@ Sensai76, belki de ancak dönüşümün sıkıntı verici bir yük olacağından kuşkuluyum (bunun diğer ipler tarafından nasıl kullanıldığını bilmeden söylemek zor olsa da) ve bunun bir türden daha fazla bir yük olacağı söylenir. kilit. –

2

Bu mümkün değil - alana erişimi senkronize etmek için lock veya Monitor sınıfını kullanmanız gerekecektir. Bu, DateTime'un bir değer türü olduğu - bir dayanıklılık olduğundan, budur. MSDN

-volatile (C# Reference):

uçucu anahtar kelime bu tür alanlara uygulanabilir:

  • Referans türleri.
  • İşaretçi türleri (güvenli olmayan bir bağlamda). İşaretçinin kendisi uçucu olabilse de, işaret ettiği nesnenin yapamayacağını unutmayın. Diğer bir deyişle, bir "uçucu işaretçiyi" ilan edemezsiniz.
  • Sbyte, bayt, kısa, ushort, int, uint, char, float ve bool türleri.
  • Aşağıdaki temel türlerden birine sahip bir numara türü: bayt, sbyte, kısa, ushort, int veya uint.
  • Referans türleri olarak bilinen genel tip parametreler.
  • IntPtr ve UIntPtr. Diğerleri de söylediğim gibi

, zaman izlemek için Ticks kullanabilirsiniz.

2

Kodunuz evreli DateTime atama atomik olması garanti edilmez değil. Genelde 32 bit'e kadar olan tamsayılar atomiktir, ancak 64'ün atomik olması gerekmez.

DateTime işaretleriyle Interlocked.Exchange'u kullanabilirsiniz, çünkü bu Int64'ü atomik olarak depolayabilir.

Ancak kenelere geçiş yaparsanız, keneler için yalnızca 62 bit ve tür için 2 bit kullanıldığını bilmeniz gerekir. Yani türünü kaybetmezsin.

Ve alıcı ve ayarlayıcı atomik bir iş parçacığı güvenli hale getirseniz bile, bu yeterli olup olmadığından emin değilim. Zaman, alıcınızın döndürdüğü zaman ile gerçekte sahip olduğunuz zaman arasında çalıştığınız zaman arasında değişebileceğinden beri. Yani zamanınız her zaman güncel olmayabilir.

+0

Bu x64 makineleri için bir x64 uygulamasıdır. önemli mi? İyi bir nokta. – vtortola

+0

@vtortola buna göre, 64 bit atamaları atomik olabilir: _ CLI, işlemcinin doğal işaretçisinin boyutunun (veya daha küçük olan) değer tiplerinin değişkenlerini okuyan ve yazanların atomik olduğunu garanti eder; CLR'nin 64 bitlik bir sürümünde 64 bit işletim sisteminde C# kodu çalıştırıyorsanız, 64 bitlik çiftleri okur ve yazar ve uzun tam sayıların da atomik olduğu garanti edilir. C# dili bunu garanti etmez, ancak çalışma zamanı özellikleri https://stackoverflow.com/a/11745471/67824 –

İlgili konular