Нужно знать, когда приложение закрывается - PullRequest
7 голосов
/ 10 июня 2010

Есть ли способ контролировать, когда приложение, использующее dll, закрывается? DLL и приложение являются C # и Windows Forms.

Я могу проверить, когда закрывается основное приложение, но я бы хотел, чтобы DLL увидела: «Эй, программа закрывает и освобождает меня, я должен сделать это очень быстро, прежде чем умру».

Есть ли способ сделать это? Или я застрял с аппликацией "сделай это, прежде чем умереть"?

Ответы [ 4 ]

8 голосов
/ 10 июня 2010

Возможно, событие AppDomain.ProcessExit подойдет вам? Обратите внимание на следующее (из документов):

Общее время выполнения всех Обработчики событий ProcessExit ограничены, так же, как общее время выполнения все финализаторы ограничены в процессе неисправность. Значение по умолчанию составляет две секунды. Неуправляемый хост может изменить это время выполнения, вызвав ICLRPolicyManager :: SetTimeout метод с перечислением OPR_ProcessExit значение.

1 голос
/ 10 июня 2010

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

Если вам нужно выпуститьресурсы или очистить другие вещи детерминистическим способом, вы должны взглянуть на интерфейс IDisposable.Если классы, предоставляемые вашей библиотекой, реализуют этот интерфейс, вызывающая сторона может легко заявить, что им больше не нужна функциональность dll, вызвав Dispose().

Возможно, хорошей отправной точкой для дальнейшего прочтения являются следующие статьи:

Например, в вашей библиотеке классов может быть следующий класс:

using System;
using System.IO;

public class ResourceManager : IDisposable
{
    private Stream _resource;
    private bool _disposed;

    public void Dispose()
    {
        Dispose(true);

        // Use SupressFinalize in case a subclass
        // of this type implements a finalizer.
        GC.SuppressFinalize(this);
    }

    public void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                Console.WriteLine("Exiting Process. Cleaning up.");
                // free resources here
                if (_resource != null)
                    _resource.Dispose();
                Console.WriteLine("Object disposed.");
            }

            // Indicate that the instance has been disposed.
            _resource = null;
            _disposed = true;
        }
    }
}

В вашем основном модуле вы можете использовать его следующим образом;оператор using гарантирует, что метод Dispose() будет вызван:

using System;
using System.Windows.Forms;

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        using (ResourceManager manager = new ResourceManager())
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
0 голосов
/ 10 июня 2010

Если это Консольное приложение, вам нужно сделать как принятый ответ в этот вопрос . И лучше всего разрабатывать, используя IDisposable интерфейс.

0 голосов
/ 10 июня 2010

AppDomain.ProcessExit будет «нормально» работать, но не гарантируется, что его запуск будет завершен, например, диспетчером задач. Поэтому он может быть не идеальным, если ваш драйвер устройства должен высвобождать большие ресурсы и т. Д. (Т. Е. Они могут не высвобождаться до тех пор, пока GC не доберется до него).

Подробнее см. блог Рика Шталса .

...