Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Деструктр статического объекта


Автор: Lazin 1.3.2010, 10:00
Добрый день.

Столкнулся со следующей проблемой. У меня есть некий класс Foo, у которого есть частная переменная
Код

private AutoResetEvent complete = new AutoResetEvent(true);

в деструкторе объекта, происходит ожидание этого события
Код

~Foo()
{
    if (!complete.WaitOne(timeout))
        ....
}

объект класса Foo, является статическим членом другого класса
Код

    public class Bar
    {
        private static Foo foo;

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

Автор: azesmcar 1.3.2010, 10:22
Цитата(Lazin @  1.3.2010,  10:00 Найти цитируемый пост)
я пока не разобрался в том, что там происходит, но если убрать все вызовы complete.Set() и все вызовы complete.Reset(), по идее, приложение должно зависнуть при завершении, на вызове WaitOne, но этого не происходит...

нет, 1 раз Reset нужно вызвать, тогда будет зависать, ты же в конструктор true передал
Код

var complete = new AutoResetEvent(false);
MessageBox.Show("start");
complete.WaitOne(1000); // будет ждать!
MessageBox.Show("end");


Код

var complete = new AutoResetEvent(true);
MessageBox.Show("start");
complete.WaitOne(1000); // НЕ будет ждать
MessageBox.Show("end");


Код

var complete = new AutoResetEvent(true);
MessageBox.Show("start");
complete.Reset();
complete.WaitOne(1000); // будет ждать!
MessageBox.Show("end");


п.с. а ты уверен что в твоем случае можно полагаться на деструктор?

Автор: mrbrooks 1.3.2010, 10:34
Цитата(azesmcar @  1.3.2010,  10:22 Найти цитируемый пост)
п.с. а ты уверен что в твоем случае можно полагаться на деструктор?

Dispose()?

Автор: Lazin 1.3.2010, 10:36
пардон, у меня там false в конструкторе, должно зависать!
у меня код, после WaitOne вообще не выполняется, то есть управление попадает в WaitOne, после чего приложение завершается
Цитата(azesmcar @  1.3.2010,  10:22 Найти цитируемый пост)
п.с. а ты уверен что в твоем случае можно полагаться на деструктор?

вот я и хочу узнать, могу я на него полагаться или нет smile 
дело в том, что моя библиотека, выполняет в фоне разные операции, и перед закрытием приложения, оно должно дождаться, пока моя библиотека завершит все операции ввода/вывода
видимо придется делать это явно...

Автор: azesmcar 1.3.2010, 10:40
Цитата(Lazin @  1.3.2010,  10:36 Найти цитируемый пост)
вот я и хочу узнать, могу я на него полагаться или нет smile 

Читал как-то одну книгу, автор много страниц рассказывал о том, как написать программу, чтобы деструктор вызывался по желанию программиста, в конце нашел способ и сам же его опроверг на следующей странице smile 


Цитата(Lazin @  1.3.2010,  10:36 Найти цитируемый пост)
у меня код, после WaitOne вообще не выполняется, то есть управление попадает в WaitOne, после чего приложение завершается

завершается? а может exception? по дебагером смотрел?

Автор: Lazin 1.3.2010, 10:44
завернул вызов WaitOne в блок try catch - результат абсолютно такой-же... заходим в WaitOne, проходит несколько секунд и приложение завершается

Добавлено через 16 секунд
Цитата(azesmcar @  1.3.2010,  10:40 Найти цитируемый пост)
по дебагером смотрел?

только под ним и запускал )

Автор: azesmcar 1.3.2010, 10:54
Цитата(Lazin @  1.3.2010,  10:44 Найти цитируемый пост)
завернул вызов WaitOne в блок try catch - результат абсолютно такой-же... заходим в WaitOne, проходит несколько секунд и приложение завершается

Да, ты прав..скорее всего .NET убивает, проверил вот такой код
Код

namespace ConsoleApplication1
{
    class A
    {
        private AutoResetEvent _complete = new AutoResetEvent(false);

        public A()
        {
        }

        ~A()
        {
            _complete.WaitOne(10000);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A t = new A();
        }
    }
}


он ждет, но не ждет 10 секунд, предполагаю, что .NET при очистке мусора видет что деструктор что-то подвис и завершает программу (или делает что-то еще, но что-то определенно делает).

Добавлено через 6 минут и 4 секунды
Поискал, в MSDN-е ничего об этом не нашел, но скорее всего задерживать работу сборщика мусора не следует smile

Добавлено через 10 минут и 41 секунду
Цитата(Стандарт)

The garbage collector is allowed wide latitude in deciding when to collect objects and run destructors. Specifically, the timing of destructor invocations is not deterministic, and destructors may be executed on any thread. For these and other reasons, classes should implement destructors only when no other solutions are feasible.

Автор: Lazin 1.3.2010, 11:07
нда, видимо нужно будет реализовать метод Close, и не париться
но как-то это совсем не кошерно smile 

Автор: azesmcar 1.3.2010, 11:09
Цитата(Lazin @  1.3.2010,  11:07 Найти цитируемый пост)
нда, видимо нужно будет реализовать метод Close, и не париться

А почему не реализовать IDisposable?

Автор: mrbrooks 1.3.2010, 11:12
Цитата(azesmcar @  1.3.2010,  11:09 Найти цитируемый пост)
А почему не реализовать IDisposable?

третьей мессагой меня это тоже заинтересовало   smile 
чет вы тут мутите пацаны злое  smile 

Автор: Lazin 1.3.2010, 11:25
а разве метод Dispose не вызывается сборщиком мусора?

Добавлено через 32 секунды
то есть, результат будет таким же, если не вызвать его явно, или не использовать using

Автор: mrbrooks 1.3.2010, 11:31
да

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)