Должен ли UnhandledException уведомлять обо всех необработанных исключениях? [Дубликат]

Вы можете использовать метод расширения GetMigrations класса DatabaseFacade (возвращенный свойством Database для DbContext), чтобы получить список ожидающих имен миграции.

Затем вы можете получить услугу IMigrator и использовать метод Migrate , передающий каждое целевое имя миграции:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;

DbContext db = ...;
var pendingMigrations = db.Database.GetPendingMigrations().ToList();
if (pendingMigrations.Any())
{
    var migrator = db.Database.GetService();
    foreach (var targetMigration in pendingMigrations)
        migrator.Migrate(targetMigration);
}

35
задан David Schmitt 2 January 2009 в 10:56
поделиться

5 ответов

Это потому, что вы запускаете его через Visual Studio в режиме отладки. Если вы отпустите и установите приложение в другом месте, будет обработан только ваш глобальный обработчик исключений.

29
ответ дан Peter Lindholm 25 August 2018 в 18:41
поделиться

Это поведение по дизайну.

Но там есть обход.

Либо вы вызываете Process.GetCurrentProcess().Kill(); внутри обработчика, либо просто не позволяйте обработчику закончить.

Посмотрите пример:

class Program
{
    void Run()
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        Console.WriteLine("Press enter to exit.");

        do
        {
            (new Thread(delegate()
            {
                throw new ArgumentException("ha-ha");
            })).Start();

        } while (Console.ReadLine().Trim().ToLowerInvariant() == "x");


        Console.WriteLine("last good-bye");
    }

    int r = 0;

    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Interlocked.Increment(ref r);
        Console.WriteLine("handled. {0}", r);
        Console.WriteLine("Terminating " + e.IsTerminating.ToString());

        Thread.CurrentThread.IsBackground = true;
        Thread.CurrentThread.Name = "Dead thread";            

        while (true)
            Thread.Sleep(TimeSpan.FromHours(1));
        //Process.GetCurrentProcess().Kill();
    }

    static void Main(string[] args)
    {
        Console.WriteLine("...");
        (new Program()).Run();
    }
}

Это, конечно, не должно быть по умолчанию для исключений.

Но это должно быть сделано, чтобы излагать исключения изящно.

0
ответ дан bohdan_trotsenko 25 August 2018 в 18:41
поделиться

Обратите внимание, что необработанные исключения по-прежнему довольно смертельны; вы можете реально использовать это только для регистрации или, может быть, поспешного закрытия. Ни этот, ни Application.ThreadException не могут использоваться как глобальный приемник для ошибок.

. Лучший подход - добавить правильную обработку - например, вокруг всей вашей Main() логики. Обратите внимание, что даже этот не может поймать несколько исключений, таких как ошибки во время загрузки формы (которые становятся особенно неприятными - вы можете поймать их приложением отладчика, но не без него).

7
ответ дан Marc Gravell 25 August 2018 в 18:41
поделиться
  • 1
    ну, конечно, я знаю это;) – agnieszka 2 January 2009 в 10:48
  • 2
    то почему бы не поймать их в Main ()? – Marc Gravell♦ 2 January 2009 в 11:05
  • 3
    "Я знаю, что" был ответом на «потерю ошибок», часть. Я учился увлекаться в основном - это то, чего вы не должны делать. однако, я должен сказать честно, что я не знаю, почему это будет плохой подход (конечно, если я поймаю все исключения, о которых я могу думать внутри кода) – agnieszka 2 January 2009 в 11:18

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

using System;

static class Program
{
  [STAThread]
  static void Main(string[] argv)
  {
    try
    {
      AppDomain.CurrentDomain.UnhandledException += (sender,e)
      => FatalExceptionObject(e.ExceptionObject);

      Application.ThreadException += (sender,e)
      => FatalExceptionHandler.Handle(e.Exception);

      // whatever you need/want here

      Application.Run(new MainWindow());
    }
    catch (Exception huh)
    {
      FatalExceptionHandler.Handle(huh);
    }
  }

  static void FatalExceptionObject(object exceptionObject) {
    var huh = exceptionObject as Exception;
    if (huh == null) {
      huh = new NotSupportedException(
        "Unhandled exception doesn't derive from System.Exception: "
         + exceptionObject.ToString()
      );
    }
    FatalExceptionHandler.Handle(huh);
  }
}

Может быть, это то, что вы тоже найдете полезным? Этот основной код маршрутизирует все три способа обнаружения неожиданных исключений верхнего уровня посредством одного вызова метода. Все, что вам теперь нужно, это статический класс FatalExceptionHandler, который включает в себя обработку исключений верхнего уровня в методе Handle.

И действительно, любой разработчик приложений знает, что на самом деле есть только две вещи:

  1. Показать / записать исключение, как вы видите, подходящее
  2. Убедитесь, что вы выходите / убиваете процесс приложения

Если вы думаете, что элемент два странных, помните, что мы только потрудились сделать это в первую очередь для действительно исключительных ситуаций. Эти вещи, вероятно, являются ошибками, которые нуждаются в изменениях в вашем приложении, чтобы их можно было точно решить. Любая другая обработка исключений - функциональный вид - должна быть ниже внутри вашего реального программного кода, улавливая определенные виды исключений, если это имеет смысл и обрабатывает их там, как это имеет смысл. Что-нибудь еще должно пузыриться до вашего FatalExceptionHandler, чтобы сделать себя известным и остановить возможную искалеченную программу от работы из поврежденного состояния

Мертвые программы не говорят лжи ...; -)

31
ответ дан peSHIr 25 August 2018 в 18:41
поделиться
  • 1
    +1 для мертвых программ не скажу лжи ... ;-) – Munish Goyal 30 May 2013 в 06:50
  • 2
    Как вы можете видеть из этого Почему UnhandledExceptionEventArgs.ExceptionObject - объект, а не сообщение Exception? , он может неразумно отбрасывать e.ExceptionObject в Exception без проверки во-первых, поскольку он не всегда будет иметь тип Exception ... вы могли бы создать здесь новый Exception. – Sheridan 31 July 2013 в 11:06
  • 3
    Интересно, почему это был объект, но на самом деле не смотрел на это. Я узнал что-то новое сегодня. Благодаря! Изменит ответ, чтобы попытаться исправить это. – peSHIr 31 July 2013 в 13:51
  • 4
    Не соглашайтесь здесь, по крайней мере, для интерактивного приложения с правильным использованием try ... finally ... catch blocks. В этом случае ужасная идея прекратить применение. Все необработанное исключение означает, что исключение вернуло его к основному циклу программы, что на самом деле довольно нормально, если только каждый из них не выполняет обработчики на каждом обработчике событий. Даже если это ваша политика, которая не очень сухая, вы забудете ее и заставите приложение сбой, а не просто сообщение. – N8allan 13 February 2016 в 23:00
  • 5
    Ты забрал меня на последней строчке ... – SnakeFoot 16 February 2017 в 14:04

Возможно, вы ищете Environment.Exit(int errorcode)

2
ответ дан Yariv 25 August 2018 в 18:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: