挂起工作线程并等待主线程上的用户交互

时间:2013-06-07 09:00:47

标签: c# multithreading

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

批处理可能会产生一些错误(阻塞)或警告(非阻塞)。

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

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

  1. 处理了一些数据
  2. 生成一些警告
  3. 用户评论这些消息
  4. 用户决定继续或停止批处理
  5. 批量恢复或停止
  6. 我可以直接从工作线程中创建一个ShowDialog(),但我不喜欢这个解决方案,因为这不是一个UI线程。

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

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

    这是一个如此糟糕的设计模式吗?

3 个答案:

答案 0 :(得分:4)

如果你改变了“唤醒”机制,这个概念就不错了。

不是bool?而是定期唤醒工作人员,最好使用boolManualResetEvent。工作人员通知UI并等待事件(立即阻止)。 UI与用户交互,适当地设置bool并发出事件信号(释放工作人员,检查bool值并相应地行动)。

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

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

  1. 提出“为所有警告执行此操作”选项;如果已选中,反馈服务将停止显示请求的UI,而是在内部回答它们。
  2. 以“静音模式”执行操作:反馈服务配置为在不显示UI的情况下回答请求(例如,总是说“继续”)。

答案 1 :(得分:2)

我会使用Events来做到这一点。像这样:

  1. 创建AutoResetEvent作为类成员变量
  2. 当需要使用交互时,请先重置事件
  3. 通知主要UI线程
  4. 等待活动
  5. 在主线程中:

    1. 显示警告/错误。
    2. 存储用户的选择。
    3. 设置活动。
    4. 现在,工作线程将被唤醒并获取主线程的结果(用户选择的内容)并继续。

答案 2 :(得分:1)

为什么不使用某种锁定机制而不是bool??例如ManualResetEvent可以阻止线程,直到用户决定。比他的决定可以设置此事件,导致线程继续工作。它应该继续工作的方式应该在另一个变量中传递,以明确区分阻塞机制和如何继续执行的信息。