Хитрый синглтон
От: Morpheus_  
Дата: 12.10.06 09:53
Оценка:
Задачка:

есть синглтон объект:

public class MySingleton
{
    // === static members ===
    
    private static MySingleton _inst = null;
    static MySingleton()
    {
        if(_inst==null)
            _inst = new MySingleton();
    }
    
    public static AddMsg(object msg)        // помещает месидж в очередь для обработки
    {
        Queue.Synchronized(_inst.msgQueue).Enqueue( msg );
        _inst.workEvent.Set();
    }

    public static Stop()                                // необходимо вызвать перед закрытием приложения
    {
        _inst.workActive = false;
        _inst.workEvent.Set();
        _inst.workThread.Join();
    }


    // === instance members ===

    private Queue msgQueue = new Queue();
    private Thread workThread;
    private bool workActive = false;
    private AutoResetEvent workEvent = new AutoResetEvent(false);

    private MySingleton()
    {
        workThread = new Thread(new ThreadStart(workProc));
        workActive = true;
        workThread.Start();
    }
    private void workProc()                                // поток обработки очереди
    {
        Queue Q = Queue.Synchronized(msgQueue);
        bool exit = false;
        while(true)
        {
            workEvent.WaitOne();

            if(!workActive)
                exit = true;

            while(Q.Count>0)
                processMsg(Q.Dequeue());

            if(exit)
                break;
        }
    }
    private void processMsg(object msg)        // обработка месиджа
    {
        //...
    }
}


объкет получает месиджи через вызов AddMsg и асинхронно обрабатывает их в своем потоке.
Проблема возникает при закрытии приложения — в очереди msgQueue еще остаются необработанные месиджи, а объект уничтожается.
Можно конечно из приложения вызывать метод Stop который подождет пока накопившаяся очередь будет обработана, однако хотелось бы чтобы объект сам контролировал этот момент.
Если же вызывать метод Stop из деструктора, то он не успевает обработать все месиджи — объект преждевременно уничтожается.

как это можно решить чтобы приложению не нужно было вызывать метод Stop перед закрытием?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Хитрый синглтон
От: Аноним  
Дата: 12.10.06 12:30
Оценка:
Здравствуйте, Morpheus_, Вы писали:

M_>Задачка:

M_>есть синглтон объект:
M_>....

реализуй интерфейс
IDisposable
Re[2]: Хитрый синглтон
От: Morpheus_  
Дата: 12.10.06 13:28
Оценка:
Здравствуйте, <Аноним>, Вы писали:

M_>>Задачка:

M_>>есть синглтон объект:
M_>>....

А>реализуй интерфейс
IDisposable


сам интерфейс мне не нужен, т.к. экземпляр объекта полностью закрыт и доступен только статическим мемберам.

Дело в том что GC при закрытии приложения дает максимум 2 секунды для обработки деструктора (который и вызывает Dispose ), можно ли это время продлить?
или может есть какието другие варианты решения этой задачи?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Хитрый синглтон
От: Morpheus_  
Дата: 12.10.06 14:25
Оценка:
M_>>>Задачка:
M_>>>есть синглтон объект:
M_>>>....

M_>>>или может есть какието другие варианты решения этой задачи?


попробовал добавить в конструктор подписку на Application.ApplicationExit и Application.ExitThread, но они почемуто не вызываются

    private MySingleton()
    {
        workThread = new Thread(new ThreadStart(workProc));
        workActive = true;
        workThread.Start();
                Application.ThreadExit += new EventHandler(appExitHandler);    // <- почемуто не работает :(
    }
        private void appExitHandler(object sender, EventArgs e)
        {
            Console.WriteLine("appExitHandler...");
            Stop();
        }


не работает, может ктото подскажет почему?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Хитрый синглтон
От: GlebZ Россия  
Дата: 12.10.06 15:07
Оценка: 2 (1)
Здравствуйте, Morpheus_, Вы писали:
Делай через AppDomain.ProcessExit или AppDomain.DomainUnload
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Хитрый синглтон
От: Morpheus_  
Дата: 12.10.06 15:48
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Здравствуйте, Morpheus_, Вы писали:

GZ>Делай через AppDomain.ProcessExit или AppDomain.DomainUnload

спасибо, заработало:
    private MySingleton()
    {
        workThread = new Thread(new ThreadStart(workProc));
        workActive = true;
        workThread.Start();
                AppDomain.CurrentDomain.ProcessExit += new EventHandler(appExitHandler);    // <- работает :)
    }


... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.