我正在开发一个非常复杂的 winforms 应用程序,并且有大量的回调链在各处传递。
作为一个大致基于此代码的示例,可能有一个“Manager”类,它生成一个类“SetUpWorkerThreads”类,该类为 10 个 worker 创建一个“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 应用程序中,以及当大量线程正在进行时?
最佳答案
我看不出线程或多或少会带来问题。
一种替代方法是使用事件而不是回调,但这不会打断长链,而且还会给您带来取消订阅的痛苦。
一种可能的方法是创建一个负责处理所有事件的对象。作为单例或作为传递给所有线程(而不是回调)的单个对象。然后你可以在 EventRouter 对象上有一个简单的接口(interface)来从线程引发事件。然后,您可以订阅 EventRouter 上需要处理“发生的事情”的事件。
编辑
GoF 模式的一些东西 Mediator但有一个发布者-订阅者的扭曲。
关于c# - Winforms 应用程序中的可怕 "Callback chains",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7594037/