2013-08-22 1 views
3

Я хотел сделать это, чтобы проверить свой код. Я предполагаю, что я мог бы сделать еще одну оболочку вокруг объекта weakreference, но предпочел бы работать непосредственно, чтобы имитировать исходный объект, который был исправлен.Как заставить WeakReference умереть?

Это код, который я до сих пор

var myString = "someString"; 
var myStringRef = new WeakReference(myString); 
myString = null; 
GC.Collect(); 
Assert.IsFalse(myStringRef.IsAlive) //I want this to pass, but it failed. IsAlive is still true. 

Что я могу сделать, чтобы заставить последнюю строку выше не обязательно (то есть. !IsAlive)

У меня есть некоторые рамки логики, что делает домашнее хозяйство основанный на статусе слабой ссылки. Я хочу быть в состоянии проверить эту логику, чтобы сделать это, мне нужно иметь возможность изменять состояние слабой ссылки по своему усмотрению - так как я могу это сделать?

+0

Не задан точный дубликат, но [аналогичный вопрос] (http://stackoverflow.com/questions/208387/weakreference-bug). –

ответ

1

Вместо жесткого кодирования строки в исходный файл, прочитайте ее через внешний источник. Например, вы можете создать файл TestStrings.txt, где размещаются ваши строки (строки), и использовать это.

string myString = File.ReadAllText(@"TestStrings.txt");   

var myStringRef = new WeakReference(myString); 
myString = null; 

GC.Collect(); 
Assert.IsFalse(myStringRef.IsAlive); 

Это должно возвращать значение false. Как уже упоминалось в другом ответе, это действительно связано с интернированием строк.

Прочитав текст с внешнего источника, строки не будут интернированы здесь, что, кажется, является тем, что вы хотите для этого теста. (Вы можете проверить, является ли строка интернированной, используя метод).

+0

Спасибо, это очень подробно. – Alwyn

+0

Добро пожаловать :) – keyboardP

3

Интересно, если это что-то из-за с тем, что строки интернирован, потому что следующий тест пройден:

var myObject = new object(); 
    var myObjectRef = new WeakReference(myObject); 
    myObject = null; 
    GC.Collect(); 
    Assert.IsFalse(myObjectRef.IsAlive); 
+0

Следующий тест проходит только от .NET 4.5 и выше. –

0

, чтобы сделать это, мне нужно, чтобы иметь возможность изменить состояние WeakReference на будет

вы могли бы построить абстракции вокруг WeakReference и сделать что тестируемый (с использованием в «тестовый режим», который позволяет изменять значение, возвращенное IsAlive интерфейс или).

2

Литеральные строки интернированы по умолчанию, поэтому, несмотря на то, что вы null myString экземпляр по-прежнему коренится в таблице intern.

См. my answer по этому вопросу для получения подробной информации о том, как обрабатывается интернирование.