обработка исключений верхнего уровня с обработчиками событий в c # - PullRequest
1 голос
/ 13 мая 2009

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

Я начну объяснять, чего бы я хотел достичь в своем приложении на c #:

У меня есть метод верхнего уровня (назовем его основным методом). Этот метод вызывает асинхронный метод (который называется connect), который подключается к FTP-серверу.

С этим соединением связан объект EventHandler, а при успешном соединении вызывается метод обратного вызова.

Я хочу обработать исключения, которые могут быть запущены в течение всего процесса. Поэтому я хотел бы поймать это в методе верхнего уровня. Он отлично работает для исключений, запускаемых методом connect (который вызывается внутри метода верхнего уровня). Однако он не работает для исключений, вызываемых внутри метода «обратного вызова»: метод верхнего уровня не перехватывает их и выполнение завершается неудачей.

Что я могу сделать, чтобы эти исключения были обнаружены методом верхнего уровня? Я не хочу обрабатывать эти исключения в обратном вызове.

Ответы [ 5 ]

2 голосов
/ 13 мая 2009

Посмотрите, как Фоновый работник справляется с этим: Исключение передается обработчику событий Completed.

Я предполагаю, что у вас есть какая-то форма объекта State, которая передается в / из делегата, вот где вы можете добавить такое свойство. И вам придется перехватывать все исключения в потоке, в самой внешней области видимости. Но «обработка» - это просто передача.

Существует стандартный шаблон для события RunWorkerCompleted, см. эту страницу MSDN .

2 голосов
/ 13 мая 2009

Рассмотрим фрагмент кода ниже для упаковки всего вашего кода в глобальный обработчик исключений:

namespace MyClient
{
  class Program
  {
    static void Main(string[] args)
    {
      try
      {
        bool isSuccess = SubMain(string[] args);
      }
      catch (Exception e)
      {
        HandleExceptionGracefully(e);
      }
    }
    static bool SubMain(string[] agrs)
    {
       // Do something
    }
    static void HandleExceptionGracefully(Exception e)
    {
       // Display/Send the exception in a graceful manner to the user/admin.
    }
  }
}

Кроме того, не забудьте сделать обработку ошибок удобной для пользователя.

1 голос
/ 13 мая 2009

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


Отредактировано:

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

BackgroundWorker в Winforms делает что-то похожее.

0 голосов
/ 18 мая 2009

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

Эти делегаты c # позволяют вызывать методы асинхронно. И делегаты позволяют также обработку исключений верхнего уровня. Действительно, исключения, сгенерированные внутри делегатов, повторно генерируются в исходном потоке.

Не знаю, почему я раньше не думал о делегатах. Я надеюсь, что это поможет.

Смотрите эти хорошие статьи о делегатах:

Артикул 1

Статья 2

0 голосов
/ 14 мая 2009

Спасибо за ваши ответы.

Кажется, что использование BackgroundWorker решает эту проблему.

Я не пробовал, потому что я решил избежать этого бремени реализации. Поэтому я забрал свой асинхронный вызов и заставил мое приложение работать синхронно.

Один совет для людей, использующих Compact Framework вместо полной .NET Framework: BackgroundWorker недоступен в CF, но OpenNETCF предоставляет аналогичное решение (см. класс BackgroundWorker в Smart Device Framework).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...