C# 挂起工作线程并在主线程上等待用户交互

C# 挂起工作线程并在主线程上等待用户交互,c#,multithreading,C#,Multithreading,我有一个主UI线程,它在工作线程上启动SQL批处理 批处理可能会生成一些阻塞错误或非阻塞警告 在第一种情况下,我最终回滚事务并退出线程 在第二种情况下,我希望用户查看SQL批处理中间的警告消息: 一些数据被处理 会生成一些警告 用户查看这些消息 用户决定继续或停止批处理 批处理继续或停止 我可以直接从工作线程创建ShowDialog,但我不喜欢这个解决方案,因为它不是UI线程 我的想法是通知主UI线程有关已生成的情况警告,并将工作线程休眠一段固定的时间,比如500毫秒。三态布尔?每次线程唤醒时都

我有一个主UI线程,它在工作线程上启动SQL批处理

批处理可能会生成一些阻塞错误或非阻塞警告

在第一种情况下,我最终回滚事务并退出线程

在第二种情况下,我希望用户查看SQL批处理中间的警告消息:

一些数据被处理 会生成一些警告 用户查看这些消息 用户决定继续或停止批处理 批处理继续或停止 我可以直接从工作线程创建ShowDialog,但我不喜欢这个解决方案,因为它不是UI线程

我的想法是通知主UI线程有关已生成的情况警告,并将工作线程休眠一段固定的时间,比如500毫秒。三态布尔?每次线程唤醒时都会检查,如果没有值,则线程将再次休眠

当用户查看警告并可能决定继续时,将设置布尔值,下次工作线程将唤醒时,它将知道是继续还是安全中止回滚批处理


这是一种很糟糕的设计模式吗?

如果你改变了唤醒机制,这个概念还不错

而不是一个傻瓜?而且,定期单独叫醒工人,最好是使用bool和a。工作进程通知UI并立即等待事件。用户界面与用户交互,适当地设置bool,并向释放worker的事件发出信号,worker检查bool值并相应地采取行动

当然,上述内容可以以多种方式实现,并且实现为工程留出了相当大的空间。在规模的一端,您可以将代码与原始标志和事件紧密耦合,而在另一端,您可以拥有工作人员查询的抽象反馈服务

这将使您能够将反馈服务的一个实现替换为另一个实现,其中包括:

显示“对所有警告执行此操作”选项;如果选择了该选项,反馈服务将停止显示请求的UI,而是在内部回答请求。 在静默模式下执行操作:反馈服务被配置为在不显示UI的情况下回答请求,例如,总是说“继续”。
如果你改变唤醒机制,这个概念还不错

而不是一个傻瓜?而且,定期单独叫醒工人,最好是使用bool和a。工作进程通知UI并立即等待事件。用户界面与用户交互,适当地设置bool,并向释放worker的事件发出信号,worker检查bool值并相应地采取行动

当然,上述内容可以以多种方式实现,并且实现为工程留出了相当大的空间。在规模的一端,您可以将代码与原始标志和事件紧密耦合,而在另一端,您可以拥有工作人员查询的抽象反馈服务

这将使您能够将反馈服务的一个实现替换为另一个实现,其中包括:

显示“对所有警告执行此操作”选项;如果选择了该选项,反馈服务将停止显示请求的UI,而是在内部回答请求。 在静默模式下执行操作:反馈服务被配置为在不显示UI的情况下回答请求,例如,总是说“继续”。
我会用事件来做这件事。像这样:

创建一个AutoResetEvent作为类成员变量 当需要使用交互时,首先重置事件 通知主UI线程 等待事件 在主线程中:

显示警告/错误。 存储用户选择的内容。 设置事件。
现在,工作线程将被唤醒,并获取用户选择并继续执行的主线程结果。

我将使用事件来完成此操作。像这样:

创建一个AutoResetEvent作为类成员变量 当需要使用交互时,首先重置事件 通知主UI线程 等待事件 在主线程中:

显示警告/错误。 存储用户选择的内容。 设置事件。 现在,工作线程将被唤醒,并获得用户选择的主线程的结果。与其使用bool?,为什么不使用一些锁定机制呢?例如,ManualResetEvent可能会阻塞线程,直到用户决定。他的决定可能会引发此事件,导致线程继续工作。它应该继续工作的方式应该在另一个变量中传递,以明确区分阻塞机制和如何继续执行的信息。

与其使用bool?,为什么不使用一些锁定机制呢?例如,ManualResetEvent可能会阻塞线程,直到用户决定。他的决定可能会引发此事件,导致线程继续工作。它应该继续工作的方式应该在另一个变量中传递,以明确区分mec和mec
hanism感谢您的阻止和关于如何继续执行的信息。

感谢您的完整回答。还有一个问题:为什么我必须使用MRE而不是ARE?我只有一个工作线程,所以在我看来,工作线程释放后自动重置将是一个很好的功能…@Teejay:理想情况下,工作线程会在请求反馈方法中阻塞,因此它不会知道所使用的事件类型。反馈服务可以很好地使用ARE,我只是在默认情况下追求最大的灵活性:为每个请求创建一个新的MRE并在每次请求后丢弃。实际上,它与重用单个ARE一样方便,虽然它可能更浪费资源,但我们应该警惕过早优化。我的意见不是通过重用单个ARE来过早优化代码。简单地说,是似乎更方便我的具体情况,纠正我,如果我错了@蒂杰:我想你的意思是方便,因为你需要更少的代码。这将取决于您如何实现,通常是的,它需要更少的代码。单纯地想象一下,虽然我认为随着实现质量的提高,节省的金额会减少。我实现了您的解决方案,它工作得非常完美。非常感谢。谢谢你完整的回答。还有一个问题:为什么我必须使用MRE而不是ARE?我只有一个工作线程,所以在我看来,工作线程释放后自动重置将是一个很好的功能…@Teejay:理想情况下,工作线程会在请求反馈方法中阻塞,因此它不会知道所使用的事件类型。反馈服务可以很好地使用ARE,我只是在默认情况下追求最大的灵活性:为每个请求创建一个新的MRE并在每次请求后丢弃。实际上,它与重用单个ARE一样方便,虽然它可能更浪费资源,但我们应该警惕过早优化。我的意见不是通过重用单个ARE来过早优化代码。简单地说,是似乎更方便我的具体情况,纠正我,如果我错了@蒂杰:我想你的意思是方便,因为你需要更少的代码。这将取决于您如何实现,通常是的,它需要更少的代码。单纯地想象一下,虽然我认为随着实现质量的提高,节省的金额会减少。我实现了您的解决方案,它工作得非常完美。非常感谢。