可怕的“回调链”在winforms应用程序中

发布于 2024-12-06 20:27:25 字数 1416 浏览 1 评论 0原文

我正在开发一个非常复杂的 winforms 应用程序,并且有大量的回调链在各处传递。

作为一个松散地基于此代码的示例,可能有一个“Manager”类,它生成一个“SetUpWorkerThreads”类,该类为 10 个工作人员创建一个“HandleWorker”线程。 工作线程有时需要回调管理器类,为了实现这一点,代码如下所示:

public class Manager
{
    public delegate void SomethingHappenedHandler();

    private void Init()
    {
        var x = new SetUpWorkerThreads(SomethingHappened);
    }

    private void SomethingHappened()
    {
        // Handle something happened
    }

}

public class SetUpWorkerThreads
{
    private readonly Manager.SomethingHappenedHandler _somethingHappened;

    public SetUpWorkerThreads(Manager.SomethingHappenedHandler somethingHappened)
    {
        _somethingHappened = somethingHappened;
    }

    public void SetupTheThreads()
    {
        // Contrived!
        for (int x=0; x<10; x++)
        {
            var worker = new Worker(_somethingHappened);
            new Thread(worker.DoingSomething).Start();
        }
    }
}

public class Worker
{
    private readonly Manager.SomethingHappenedHandler _somethingHappened;

    public Worker(Manager.SomethingHappenedHandler somethingHappened)
    {
        _somethingHappened = somethingHappened;
    }

    public void DoingSomething()
    {
        // ... Do Something
        _somethingHappened();
    }
}

实际上,可能涉及更多的类,每个类都会传递大量针对各种事物的回调。我意识到糟糕的类/应用程序设计在其中发挥了一定作用,但是是否有更好的方法来处理类之间的这些交互,特别是在 winforms 应用程序中,以及当大量线程正在进行时?

I'm working on a winforms application that is very complicated, and has massive callback chains being passed around all over the place.

As an example loosely based on this code, there could be a "Manager" class, that spawns a class "SetUpWorkerThreads" class, which creates a "HandleWorker" thread for say 10 workers.
The worker thread needs to call back to the manager class on occasion, to achieve this the code looks like this:

public class Manager
{
    public delegate void SomethingHappenedHandler();

    private void Init()
    {
        var x = new SetUpWorkerThreads(SomethingHappened);
    }

    private void SomethingHappened()
    {
        // Handle something happened
    }

}

public class SetUpWorkerThreads
{
    private readonly Manager.SomethingHappenedHandler _somethingHappened;

    public SetUpWorkerThreads(Manager.SomethingHappenedHandler somethingHappened)
    {
        _somethingHappened = somethingHappened;
    }

    public void SetupTheThreads()
    {
        // Contrived!
        for (int x=0; x<10; x++)
        {
            var worker = new Worker(_somethingHappened);
            new Thread(worker.DoingSomething).Start();
        }
    }
}

public class Worker
{
    private readonly Manager.SomethingHappenedHandler _somethingHappened;

    public Worker(Manager.SomethingHappenedHandler somethingHappened)
    {
        _somethingHappened = somethingHappened;
    }

    public void DoingSomething()
    {
        // ... Do Something
        _somethingHappened();
    }
}

In reality, there can be many more classes involved, each passing around a mass of callbacks for various things. I realise that poor class/application design is playing a part in this, but are there better ways to go about handling these interactions between classes, specifically in winforms apps, and when a lot of threading is going on?

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

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

发布评论

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

评论(1

神回复 2024-12-13 20:27:25

我看不出线程或多或少会带来问题。
一种替代方法是使用事件而不是回调,但这不会打破长链,并且还会给您带来取消订阅的痛苦。

一种可能的方法是创建一个负责处理所有事件的对象。作为单例或作为传递给所有线程的单个对象(而不是回调)。然后,您可以在 EventRouter 对象上有一个简单的接口来从线程引发事件。然后,您可以订阅 EventRouter 上需要处理“发生的事情”的事件。

编辑
GoF 模式中介者,但具有发布者-订阅者的特点。

I can't see that the threading makes it more or less problematic.
One alternative is to use events instead of callbacks, but that won't break up the long chains and will give you an unsubscribing hell too.

One possible approach is to create an object responsible for handling all the events. Either as a singleton or as a single object that you pass to all your threads (instead of the callbacks). Then you can have a simple interface on the EventRouter object to raise events from the threads. You can then subscribe to events on the EventRouter where you need to handle "something happened".

Edit
Something the GoF pattern Mediator but with a publisher-subscriber twist.

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