Обработка событий OnError в библиотеке классов - PullRequest
1 голос
/ 29 сентября 2011

Я пишу библиотеку классов, которая оборачивает различные объекты (в основном драйверы устройств для аппаратных компонентов USB)

Некоторые классы этих драйверов устройств предоставляют событие типа «OnError»: короче, если в драйвере устройства произошла ошибка во время выполнения или другая ошибка, событие запускается. Что-то вроде:

    AddHandler oDevice.DriverRunTimeErrorEvent, 
               AddressOf HandleDriverRunTimeErrorEvent

    Private Sub HandleDriverRunTimeErrorEvent(
                ByVal sender As Object,
                ByVal eventData As DriverRunTimeErrorEventArgs)
        'handle the error
    End Sub

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

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

  1. Я мог бы переслать решение драйвера устройства и сгенерировать новое событие в библиотеке классов. Затем клиент должен обработать перенаправленное событие.

  2. Но я также мог бы выдать исключение со всей информацией об ошибке

  3. Я мог бы просто проигнорировать ошибку и просто зарегистрировать ее в файле протокола.

Решение 1. мне кажется более надежным, и я бы использовал его, но оно не «близко» к миру .NET.

Решение 2. выдает ошибку асинхронно с потоком программы: в клиентском приложении у меня не было бы блока try-catch, который мог бы его перехватить. Другими словами, класс может выдать ошибку, если клиент не вызвал какой-либо метод класса. Конечно, я мог бы перехватывать все ошибки на уровне приложения, но в любом случае это вносит некоторую нечеткость в логику, которой я бы предпочел избегать.

Как бы вы обработали эти события OnError?

Ответы [ 2 ]

1 голос
/ 29 сентября 2011

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

Выбор между 1 и 2 зависит от общего подхода, который вы выбираете для предоставления информации об ошибках своим пользователям. В мире .NET выбрасывание исключений является предпочтительным, по крайней мере, в стандартных ситуациях, и под стандартом я имею в виду синхронность вашего интерфейса. Если ваши пользователи вызывают метод вашего класса и ждут, когда вы вернете значение (или просто закончите выполнение), вы должны выбросить исключение, если что-то не так «достаточно»

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

Существует еще одна причина, по которой вам может потребоваться реализовать уведомления об ошибках, не основанные на исключениях. У вас все еще может быть синхронная модель - клиенты звонят вам и ждут завершения вашей операции - и затем вы можете (и вам следует) использовать события для уведомления вызывающей стороны о том, что операция не может быть успешно завершена. Но у вас может быть различие между чем-то, что происходит «достаточно неправильно» и «слегка неправильно». Рассмотрим следующий сценарий:

Клиент вызывает метод, вы запускаете асинхронную операцию, но в какой-то момент начинаете ждать ее завершения, например, с Thread.Join или WaitHandle.WaitOne. Когда рабочий поток в конце концов завершается, вы возвращаете результат пользователю. Вы можете подписаться на событие ошибки из базовой структуры - но вы можете идентифицировать эту ошибку как не фатальную, поэтому вместо генерации исключения вы можете продолжить ожидание завершения фонового потока, но в любом случае уведомить пользователя об ошибке ( опять же - только если вам нужно, довольно часто вы можете уйти, просто войдя в систему). Это можно сделать либо с помощью событий, либо с помощью возвращаемого значения (или параметра ref / out). Последний является более распространенным подходом - вы просто возвращаете список несмертельных ошибок, которые в большинстве случаев будут пустыми, и, если клиенту не все равно, - он пойдет по списку.

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

0 голосов
/ 29 сентября 2011

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

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