2013-05-27 32 views
10

Tôi đã là một vấn đề với WeakReferences trong .NET 4.x, Tôi đã chạy thử nghiệm để đảm bảo một số đối tượng không được tham chiếu nữa (sử dụng WeakReferences) và tôi nhận thấy hành vi này là không đồng nhất giữa các phiên bản khuôn khổ:Làm thế nào để buộc thu gom rác đầy đủ trong .NET 4.x?

using System; 
using System.Text; 
using NUnit.Framework; 

[TestFixture] 
public class WeakReferenceTests 
{ 
    [Test] 
    public void TestWeakReferenceIsDisposed() 
    { 
     WeakReference weakRef = new WeakReference(new StringBuilder("Hello")); 

     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
     GC.WaitForFullGCComplete(); 
     GC.Collect(); 

     var retrievedSb = weakRef.Target as StringBuilder; 
     Assert.That(retrievedSb, Is.Null); 
    } 
} 

Kết quả:

.NET 2.0 PASS 
.NET 3.0 FAIL 
.NET 3.5 PASS 
.NET 4.0 FAIL 
.NET 4.5 FAIL 

đây có phải là tài liệu ở đâu?

Có cách nào để buộc GC thu thập tham chiếu đó trong .NET 4.5 không?

Xin cảm ơn trước.

+4

Chỉ cần một lưu ý: GC không thu thập đồ vật không thể truy cập trong chế độ gỡ lỗi. – 2kay

+0

Cảm ơn tôi sẽ xem xét rằng – Guillaume86

+0

Hmm, mã bạn đã hiển thị hoạt động cho tôi trên tất cả các phiên bản của khung. (Vâng, tôi không có NUnit cài đặt, vì vậy tôi chỉ sử dụng 'Debug.Assert' nhưng điều đó không nên thay đổi hành vi.) –

Trả lời

6

Sự cố ở đây có liên quan đến NCrunch. Mã này hoạt động tốt trên máy tính của tôi cho tất cả các phiên bản của khuôn khổ này nếu tôi thay thế các thử nghiệm với một cuộc gọi đơn giản để Debug.Assert:

using System; 
using System.Text; 
using System.Diagnostics; 

public class WeakReferenceTests 
{ 
    public void TestWeakReferenceIsDisposed() 
    { 
     WeakReference weakRef = new WeakReference(new StringBuilder("Hello")); 

     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
     GC.WaitForFullGCComplete(); 
     GC.Collect(); 

     var retrievedSb = weakRef.Target as StringBuilder; 
     Debug.Assert(retrievedSb == null); 
    } 
} 
+0

Cảm ơn, đó là NCrunch rằng các công cụ lắp ráp, tôi vô hiệu hóa tùy chọn và nó vượt qua. – Guillaume86

+0

Tôi đang cố thực hiện việc này, nhưng ứng dụng của tôi được xây dựng trên Silverlight 4 và tôi không có tùy chọn WaitForFullGCComplete. Nó sẽ được trên SL5? –

0

Nhờ @ Cody Gray (xem nhận xét), tôi đã hiểu điều đó.

Tôi sử dụng NCrunch để chạy thử nghiệm của mình và nó đã được thiết bị lắp ráp đầu ra, tạo ra hành vi này (vô hiệu hóa thiết bị đầu ra làm cho vượt qua kiểm tra trên tất cả các nền tảng).

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