Как обеспечить сохранение состояния приложения при сбое c # - PullRequest
3 голосов
/ 17 февраля 2012

Я очень новичок в программировании на c #, так что помните:

У меня есть объект данных в памяти с данными, которые мне нужны для сохранения информации, когда (если) мое приложение было аварийно завершено ИЛИ закрыто. Есть ли способ сделать это детерминистически или надежно?

Я смотрю на деструкторов

~MyObjectName(){}

финализаторы и утилизация (),

но насколько я понимаю, ни один из них не будет надежно делать то, что я хочу?

В настоящее время я использую деструктор, и он работает, когда я закрываю программу, но это не значит, что он будет работать при сбое или всегда.

Должен ли я также смотреть на события?

Ответы [ 3 ]

7 голосов
/ 17 февраля 2012

Существует нет 100% надежный механизм, который вы можете использовать для сохранения данных (или делать что-либо еще в этом отношении), когда процесс (любой процесс, а не просто .Net-процесс) завершается - большинство процессовможет быть прервана в любой момент с помощью опции «Завершить процесс» в диспетчере задач, когда это происходит, процесс немедленно завершается.В качестве более экстремального примера можно выдернуть шнур питания из задней части машины.

Если нет необходимости на 100% обновлять этот объект данных и сохранять его после завершения процесса, тогда Событие AppDomain.UnhandledException может быть достаточно.

Если это абсолютно необходимо на 100%, то вам необходимо постоянно сохранять эту информацию во время выполнения процесса - нет абсолютно никакой гарантии, чтоу вас будет возможность сделать это позже.Так работают базы данных, ни одна транзакция не возвращается, пока некоторая запись об изменении не будет записана на диск в каком-либо формате (например, журнал транзакций).Это то, что D обозначает в ACID .

5 голосов
/ 17 февраля 2012

Я полагаю, что вы ищете ловить необработанные исключения? как то так:

static void Main()
{
  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(false);

  Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
  AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

  Application.Run(new Form1());
}

static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
  MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
  // here you can log the exception ...
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
  MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
  // here you can log the exception ...
}

В этом примере показано, как управлять всеми исключениями, которые не были в разделах try-catch (в приложении Windows Forms).

Событие UnhandledException обрабатывает необработанные исключения, выброшенные из основной поток пользовательского интерфейса. Событие ThreadException обрабатывает необработанные исключения, созданные в потоках не из пользовательского интерфейса.

1 голос
/ 23 марта 2012

Этого можно добиться с помощью windbg.

  1. Оставьте точку останова в методе zwterminateprocess в windbg.Этот метод будет вызываться при выходе из приложения.
  2. когда достигается точка останова, используйте! Dumpheap -type MyObjectName, чтобы получить адрес вашего объекта
  3. Используйте! Dumpobject "address of MyObjectName", чтобы узнать значения внутри объекта
...