我有一个简单的问题,但我大约80%确定问题的答案将伴随着“你做错了”的回答,所以我也会问个不简单的问题。
简单问题:我有一个公共类的公共方法。如果在UI线程上调用它,则希望它抛出异常。我该怎么做?
更不简单的问题是:是否有更容易重构这个设计的方法?
背景:
我开发了一个桌面程序,通过其API与遗留应用进行交互。该API不支持远程线程安全。我建立了一个类库,尽可能地封装与API的交互(这涉及到在巨大的byte []缓冲区中编组和解组数据,然后调用从DLL加载的外部函数)。因为我知道创建多个核心API对象会是一场灾难,所以我将其实现为静态类。
我还构建了一组在我的应用程序后台运行任务的类。 TaskManager
维护Task
对象队列,并使用BackgroundWorker
运行它们。使用后台线程可以在进行与混乱的旧版应用程序的交互时保持桌面应用程序的UI响应性;使用队列确保在任何给定时间只有一个任务正在调用API。
不幸的是,我从没想过在这个设计中建立某些保障措施。最近我发现了代码中直接在UI线程上调用API的地方。我相信我已经修复了它们,但我想保证我不会再犯同样的错误。
如果我从一开始就正确地设计了这个东西,我将API包装器类设置为非静态类,使其构造函数对除TaskManager
之外的所有内容进行隐藏,并将API类的实例传递给创建每个Task
时。任何Task
调用的方法都需要传递API对象。这将使在前台线程上使用API变得不可能。
问题是,有很多代码与API交互。实施此更改(我认为最终是正确的事情)将触及所有内容。所以在此期间,我想修改API的Call
方法,以便在前台线程上调用时抛出异常。
我知道我正在解决错误的问题。我可以感受到它在我的骨头里。但我现在也被它缠住了,无法找到正确的解决方案。
编辑:
我之前提出的问题表述不清,所以很难回答。我的问题不应该是“这个方法如何知道它是否在UI线程上运行?”真正的问题是:“这个方法如何知道它是否在错误的线程上运行?”理论上可能有一千个线程在运行。正如JaredPar所指出的那样,可能会有多个UI线程。只有一个线程是正确的线程,而且它的线程ID很容易找到。
事实上,即使我重构这段代码,使其设计得更好(今天我大部分时间都在做这件事),也值得在API中添加机制来检查它是否在适当的线程上运行。