IO thread alert GUI thread, если происходит ошибка - PullRequest
1 голос
/ 20 августа 2010

У меня вопрос клиент / сервер, для которого я пытаюсь найти лучшее решение.

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

То, как я думал об этом до сих пор:

1) Создайте объект, который создает и показывает каждый графический интерфейс. Таким образом, вместо вызова invokeLater ... SomeGui.CreateAndShoGui () ... мы бы взяли на себя ответственность за выполнение этого объекта, то есть GuiObject.showSomeGui ();

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

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

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

Спасибо

EDIT: Другой вариант, с которым я играю, это наличие объекта в потоке ввода-вывода, который также передается каждому новому графическому интерфейсу при его открытии. Этот объект возвращает текущую открытую ссылку guis обратно в поток io, так что поток io может предупредить его, если что-то пойдет не так. Однако я опираюсь на это решение, потому что кажется, что было бы легче читать, если бы у вас был один объект, который был выделен для этой работы (как вышеупомянутое решение), вместо того, чтобы передавать какой-то неясный объект каждому графическому интерфейсу.

1 Ответ

2 голосов
/ 20 августа 2010

Позвольте мне пройтись по каждой из ваших идей:

1) Плохая идея - вы связываете все свое приложение вместе через один объект.Это затрудняет ремонтопригодность и является противоположностью модульности.

2) Это путь ИМХО.Поскольку кажется, что каждый графический интерфейс имеет уникальную логику в сценарии сбоя, то вполне понятно, что объект, который лучше всего понимает, что делать, это сам объект графического интерфейса.

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

3) Это прекрасно дополняет # 2.Итак, позвольте мне получить это прямо - у вас будет 3 потока: поток ввода-вывода, поток монитора и поток пользовательского интерфейса.Я не знаю, нужна ли вам нить монитора.Исходя из того, что вы говорили, поток ввода-вывода мог бы самостоятельно обнаружить проблему с подключением (возможно, потому, что была обнаружена некоторая форма исключения IOException).Когда обнаружена проблема с подключением, поток ввода-вывода не занят, так как он скоро собирается отключиться, так что он может просто нести ответственность за уведомление графического интерфейса о наличии проблемы.В любом случае у guis должен быть вызван их интерфейсный метод в потоке пользовательского интерфейса, поэтому поток ввода-вывода просто вызывает несколько вызовов invokeLater () (или asyncExec () для SWT), а затем поток ввода-вывода может просто отключиться.

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

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

Редактировать: Я бы использовал модель событий.Допустим, вы создаете интерфейс, подобный следующему:

public interface ConnectionFailureListener {
    void handleConnectionFailure(); // Add an event object if you need it
}

Затем вы можете иметь методы регистрации в каком-либо объекте (может быть, Runnable для потока ввода-вывода или где-то еще, что вам удобно).Эти методы будут довольно стандартными:

public void addConnectionFailureListener(ConnectionFailureListener l) {}
public void removeConnectionFailureListener(ConnectionFailureListener l) {}

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

Таким образом, если у вас возникла ошибкапросто прокрутите текущие зарегистрированные слушатели, и слушатель делает свое дело.

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