如果发生错误,IO 线程向 GUI 线程发出警报

发布于 2024-09-14 19:05:41 字数 834 浏览 6 评论 0原文

我有一个客户端/服务器问题,我正在尝试找出最佳解决方案。

如果客户端出于任何原因与服务器断开连接,我希望输入输出线程有一种方法可以警告 gui 线程出现问题,从而让 gui 线程打印错误并优雅地处理它(可能会丢弃返回到登录 GUI)。创建初始 gui 线程后,客户端可以更改为任意数量的 gui,具体取决于他正在做什么,所以我想我需要一种方法来动态查看当前正在运行的 gui。

到目前为止我正在考虑这样做的方式:

1)创建一个创建并显示每个 gui 的对象。因此,我们不应该调用 invokeLater...SomeGui.CreateAndShoGui()...,而是让这个对象负责执行此操作,即 GuiObject.showSomeGui();

2) 让每个 gui 实现一个接口,这将确保有一个方法,当我们失去与服务器的连接时,该方法将正常关闭该 gui。

3)有一个线程监视IO线程和gui对象。如果 IO 线程出现问题,IO 线程将关闭并通知监控线程我们已失去与服务器的连接。然后,监视线程可以警告任何打开的 GUI(来自 gui 对象)我们已失去连接并且需要关闭。

我刚刚开始考虑这个问题,到目前为止这是我想出的最好的解决方案。这看起来是一个不会给代码增加太多复杂性的合理解决方案吗?或者有人可以推荐一个更容易让阅读代码的人理解的解决方案吗?

谢谢

编辑: 我正在尝试的另一个选项是在 IO 线程上有一个对象,该对象也会在打开时传递给每个新的 gui。该对象会将当前打开的 guis 引用返回给 io 线程,以便 io 线程在出现问题时可以向它发出警报。不过,我倾向于这种解决方案,因为如果您有一个专门用于实现此工作的对象(如上面的解决方案),而不是向每个 gui 传递一些晦涩的对象,那么似乎会更容易阅读。

I have a client/server question that i am trying to figure out the best solution for.

If a client ever gets disconnected from the server, for any reason, i would like a way for the input output thread to alert the gui thread that something went wrong, and thus have the gui thread print an error and gracefully handle it (probably drop back out to the login gui). After the initial gui thread is created, the client could change to any number of guis, depending on what he is doing, so I am thinking i need a way to dynamically see what gui is currently being run.

The way that i was thinking of doing this so far:

1) Create an object that creates and shows every gui. So instead of calling invokeLater...SomeGui.CreateAndShoGui()... we would have this object be responsible for doing that, ie GuiObject.showSomeGui();

2) Have each gui implement an interface, which will insure there is a method that, when called, will gracefully shutdown this gui when we have lost connection to the server.

3) Have a thread that monitors the IO thread and the gui object. If something goes wrong on the IO thread, the IO thread will close down and notify the monitoring thread that we have lost connection the server. The monitoring thread could then alert any open guis (from the gui object) that we have lost connection and that it needs to shut down.

I have just started thinking about this, and so far this is the best solution i have come up with. Does this seem like a reasonable solution that wont add too much complexity to the code? Or can anyone recommend a solution that would be simpler for people reading the code to understand?

Thanks

EDIT:
The other option i am toying with is having an object on the IO thread, that also gets passed to each new gui as it is opened. This object will give the currently opened guis reference back to the io thread, so that the io thread can alert it if something goes wrong. I am leaning against this solution though, because it seems like it would be easier to read if you had one object that was dedicated to get this working (like the above solution), instead of passing some obscure object to each gui.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

[浮城] 2024-09-21 19:05:41

让我来看看你的每一个想法:

1) 坏主意 - 你通过一个对象将整个应用程序捆绑在一起。这使得可维护性变得困难,并且是模块化的对立面。

2)恕我直言,这是要走的路。由于似乎每个 gui 在故障场景中都有独特的逻辑,因此最能理解要做什么的对象就是 gui 对象本身。

这个想法的另一个版本是为每个 GUI 创建一个适配器来放入此故障逻辑。这样做的好处是你的应用程序框架和 GUI 之间的依赖关系更少。缺点是这会增加一层额外的复杂性。如果您的 gui 已经与您的应用程序非常耦合,那么我会选择接口方法。如果您想在另一个应用程序中重用您的 GUI,那么适配器方式可以帮助实现这一点。

3)这很好地补充了#2。那么让我说清楚——您将有 3 个线程:IO 线程、监视器线程和 UI 线程。我不知道你是否需要监视器线程。根据您的说法,IO 线程将能够自行检测连接问题(可能是因为捕获了某种形式的 IOException)。当发现连接问题时,IO 线程并不繁忙,因为它很快就会自行关闭,因此它可能只是负责通知 guis 出现了问题。无论如何,GUI 应该在 UI 线程上调用其接口方法,以便 IO 线程只是调用一堆 invokeLater() 调用(或 SWT 的 asyncExec() 调用),然后 IO 线程可以自行关闭。

4)(您的编辑)您基本上描述了访客模式。我认为这不是一个好的解决方案,因为调用是从 IO 线程到 gui,而不是相反。我不确定在这种情况下传递访问者对象有何帮助。

最后一个想法。如果您使界面通用(不是特定于 gui),那么您可以将此模式应用于其他资源。例如,当您失去连接时,您可能想刷新您的用户凭据(因为您谈到再次进入登录屏幕)。这并不是真正的 gui 逻辑,不应该从 gui 类中完成。

编辑:我会使用事件模型。假设您创建了一个像这样的接口:

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

然后您可以在某个对象中拥有注册方法(可能是 IO 线程的 Runnable 或其他对您来说方便的地方)。这些方法非常标准:

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

当您在屏幕上显示 gui 时,您会将其添加到注册对象中,而当您关闭 gui 时,您会将其从注册对象中删除。您可以根据需要添加其他类型的对象 - 例如,当您登录时,您可以为您的凭证系统添加一个侦听器,并在处理注销时再次将其删除。

这样,当出现故障情况时,您只需循环当前注册的侦听器,侦听器就会执行其操作。

Let me just go through each of your ideas:

1) Bad idea - you are tying your whole application together through a single object. This makes maintainability difficult and is the antithesis of modularity.

2) This is the way to go IMHO. Since it seems that each gui has unique logic in a failure scenario then it stands to reason that the object that best understands what to do would be the gui object itself.

Another version of this idea would be to create an adapter for each gui to put this failure logic into. The advantage would be you have one less dependency between your application framework and your gui. The disadvantage is that this is an extra layer of complexity. If your gui is already pretty coupled to your application then I would choose the interface method. If you want to reuse your guis in another application then the adapter way could help facilitate that.

3) This complements #2 nicely. So let me get this straight - you would have 3 threads: the IO thread, the monitor thread, and the UI thread. I don't know if you need the monitor thread. From what you were saying the IO thread would be able to detect a connection problem by itself (probably because some form of IOException was caught). When a connection problem is discovered the IO thread is not busy since it is just going to shut itself down soon so it might as well just have the responsibility of notifying the guis that there was a problem. The guis should have their interface method called on the UI thread anyways so the IO thread is just calling a bunch of invokeLater() calls (or asyncExec() calls for SWT) and then the IO thread can just shut itself down.

4) (Your Edit) You are basically describing the Visitor pattern. I do not think this is a good solution because the call is from the IO thread to the gui and not the other way around. I am not sure how passing a visitor object around will help in this case.

One final thought. If you make your interface generic (not gui specific) then you can apply this pattern to other resources. For instance you may want to flush your user credentials when you lose connection (since you talked about going to the login screen again). That isn't really gui logic and should not be done from a gui class.

Edit: I would use an event model. Let's say you create a interface like this:

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

You could then have registration methods in some object (maybe the Runnable for the IO thread or somewhere else that is convenient for you). These methods would be pretty standard:

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

When you show a gui on the screen you would add it to your registration object and when you close the gui you would remove it from the registration object. You can add other types of objects as needed - for example when you log in you can add a listener for your credential system and remove it again when log out is processed.

This way when you have a failure condition you simply loop through the currently registered listeners and the listener does its thing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文