【发布时间】:2012-12-13 13:35:09
【问题描述】:
我觉得我现在的逻辑有些问题。
我使用了一个阻塞集合来对其他 PC 进行线程安全调用。一般来说,它看起来像这样:
public class MyClass
{
private BlockingCollection<workUnit> workUnits = new BlockingCollection<workUnit>();
public void EnQueue(workUnit item)
{
workUnits.Add(item);
}
private void DeQueue()
{
while (!stopFlag)
{
workUnit item = workUnits.Take();
DoLongRunningDBStuff(workUnit);
}
}
}
现在我想将其可视化给用户。
用户应该看到
- 项目在队列中
- 项目处理已开始
- 处理结果(主要是通过/失败/异常)
现在我有些头疼。
我正在考虑执行以下操作:
有一个网格来向用户显示项目。
- 如果项目已入队,则将其添加到工作单元以及绑定到数据网格的列表中
- 如果项目已出列(已使用),请更新网格列表中的项目。
让人头疼的是,如何让这个线程安全,以及哪些部分需要是线程安全的。
如果我将一些需要时间的东西放在 workUnit.Add 后面,我认为这可能是可能的,那么数据就会混合在一起。
这样的事情可行吗?
- 如果项目已入队,请将其添加到工作单元和 UI 的附加 BlockingCollection
- 如果项目已出列,请尝试 2.BlockingCollection 并将其删除,更新状态并再次将其附加到第二个列表。
我需要在 1 和 2 附近加锁吗?如果是这样,如果等待Take,它不会完全阻止添加吗?
是否有简单的解决方案或方法来可视化,发生了什么?
【问题讨论】:
-
这是一个非常严重的阻抗失配,BlockingCollection 是线程代码中使用的一个类。 UI 基本上是线程不安全的。也存在大幅减慢代码速度的严重风险。最好不要这样做,真的。这是用户永远不必担心的实现细节。
-
@Hans:主要不是展示内部实现细节。
-
{总是忘记不要使用 enter here) 考虑以下用例:数据发送到多台 PC。这通常需要约 150 毫秒,但也可能需要长达 3 秒。在以前的产品中,有一条状态行显示数据已发送。因此,用户习惯并期望后继者也将显示信息,并且他们有一个屏幕,可以看到未成功发送的内容并可以手动触发重新发送。前者用于用户反馈某些事情正在实际发生。后者用于用户交互。
-
例如用于添加某人可以重复失败的工作或可以查找失败原因的值(机器停机,对方版本错误,双方都更改了数据和他们必须手动确认哪个是正确的,依此类推。)
标签: c# multithreading user-interface