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

时间:2011-09-29 07:43:50

标签: c# winforms multithreading delegates callback

我正在开发一个非常复杂的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应用程序中,以及当很多线程正在进行时?

1 个答案:

答案 0 :(得分:2)

我看不出线程会或多或少地造成问题 一种选择是使用事件而不是回调,但这不会打破长链并且会给你一个取消订阅的地狱。

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

修改
GoF模式Mediator,但发布商 - 订阅者扭曲。