2009-01-08 49 views
38

Các mã sau"Một tham chiếu đến một lĩnh vực không ổn định sẽ không được coi là ổn định" ý nghĩa

using System.Threading; 

class Test 
{ 
    volatile int counter = 0; 
    public void Increment() 
    { 
     Interlocked.Increment(ref counter); 
    } 
} 

Tăng cảnh báo trình biên dịch như sau:

"A reference to a volatile field will not be treated as volatile" 

Tôi có làm điều gì sai ở đây để nêu vấn đề này cảnh báo? Tại sao trình biên dịch tôi cảnh báo về điều này?

Trả lời

39

Bạn không làm gì sai. Theo documentation:

Một lĩnh vực không ổn định nên không bình thường được thông qua sử dụng một ref hoặc ra tham số, vì nó sẽ không được coi là ổn định trong phạm vi của hàm. Có ngoại lệ với điều này, chẳng hạn như khi gọi số API liên khóa.

+18

Tôi muốn nói rằng các phương pháp Interlocked vẫn không xử lý bất kỳ cách nào khác với cách chúng xử lý bất kỳ trường nào khác - nó chỉ là các trường * tất cả * được xử lý theo cách đặc biệt bởi Lồng vào nhau. –

+3

Đồng ý. Dễ bay hơi không liên quan đến API được khóa liên động. Nhưng trong một số trường hợp, nó rất hữu ích để trộn lẫn nhau và dễ bay hơi. – IamIC

+0

một chút muộn cho bữa tiệc, nhưng @IamIC: cẩn thận để xây dựng những trường hợp nào sẽ là? – jajdoo

3

Bạn nhận được lỗi vì bạn đang chuyển trường theo tham chiếu. Tôi nghĩ rằng điều này có nghĩa là phương pháp mục tiêu không có ý tưởng lĩnh vực được đánh dấu là volatile, và do đó sẽ không đối xử với nó như vậy.

30

Về cơ bản, cảnh báo là khi bạn truyền một trường dễ bay hơi bằng tham chiếu, mã gọi không biết xử lý nó theo cách dễ bay hơi. Đối với Interlocked.Increment rằng có lẽ không quan trọng, do tính chất của phương pháp - nhưng sau đó bạn không cần biến để được biến động anyway nếu bạn đang sử dụng Interlocked.

Nói chung, tôi nghĩ mình nên tránh trộn hai - nếu bạn đang dùng Interlocked, hãy làm ở mọi nơi (sử dụng Interlocked.CompareExchange(ref counter, 0, 0) để đọc). Tôi không thể nói rằng tôi sử dụng dễ bay hơi rất thường xuyên, cá nhân. Đối với các bộ đếm đơn giản, tôi có thể sử dụng sử dụng Đã khóa, nhưng tôi có nhiều khả năng sử dụng khóa cho hầu hết các tác vụ.

+0

Bạn đang nhận tôi bối rối. Trong một câu hỏi trước (395232) tôi hiểu từ câu trả lời của bạn rằng tôi cần cả Interlocked và dễ bay hơi. Bây giờ bạn nói "bạn không cần biến để dễ bay hơi dù bạn đang sử dụng Interlocked." –

+0

Không, chúng là lựa chọn thay thế cho nhau: "Hoặc tốt hơn là sử dụng Interlocked, biến dễ bay hơi hoặc khóa." Điều đó có nghĩa là cung cấp ba phương pháp * khác nhau *, không phải là phương pháp kết hợp. Đó có phải là phần gây hiểu lầm cho bạn không? –

+0

Tôi hiểu rằng trong môi trường đa xử lý, nhiều bộ đệm có thể làm cho một bộ xử lý tăng một giá trị được lưu trong bộ nhớ cache không phải là giá trị cuối cùng. Trong trường hợp đó, theo như tôi biết, một Interlocked sẽ không giúp đỡ, gây ra nó không tạo ra MemoryBarrier cần thiết để làm mới cache. –

26

Sử dụng này:

 #pragma warning disable 420 
     //      M 
     //      dM 
     //      MMr 
     //      4MMML     . 
     //      MMMMM.    xf 
     //  .    "MMMMM    .MM- 
     //  Mh..   +MMMMMM   .MMMM 
     //  .MMM.   .MMMMML.   MMMMMh 
     //  )MMMh.  MMMMMM   MMMMMMM 
     //  3MMMMx.  'MMMMMMf  xnMMMMMM" 
     //  '*MMMMM  MMMMMM.  nMMMMMMP" 
     //   *MMMMMx "MMMMM\ .MMMMMMM= 
     //   *MMMMMh "MMMMM" JMMMMMMP 
     //    MMMMMM 3MMMM. dMMMMMM   . 
     //    MMMMMM "MMMM .MMMMM(  .nnMP" 
     // =..   *MMMMx MMM" dMMMM" .nnMMMMM* 
     // "MMn...  'MMMMr 'MM MMM" .nMMMMMMM*" 
     //  "4MMMMnn.. *MMM MM MMP" .dMMMMMMM"" 
     //  ^MMMMMMMMx. *ML "M .M* .MMMMMM**" 
     //   *PMMMMMMhn. *x > M .MMMM**"" 
     //    ""**MMMMhx/.h/ .=*" 
     //      .3P"%.... 
     //     nP"  "*MMnx 
     if(Interlocked.CompareExchange(ref isLoaded, 1, 0) != 0) 
      return; 
     #pragma warning restore 420 
+10

tác phẩm nghệ thuật ascii đẹp, nhưng nó không trả lời câu hỏi –

+3

Nhưng nó có ích khi bạn hiểu các câu trả lời khác, bạn nên quyết định sử dụng cả hai khóa liên động và dễ bay hơi. – yoyo

+2

@ JaderDias - Không, nhưng nó cho bạn biết phải làm gì về cảnh báo. Đó là siêu hữu ích. - Ngoài ra các tác phẩm nghệ thuật cũng khá hài hước. – BrainSlugs83

Các vấn đề liên quan