C# 如何可视化blockingcollection
我想我现在在逻辑上有些问题 我使用阻塞集合对其他PC进行线程安全调用。通常情况下,它是这样的:C# 如何可视化blockingcollection,c#,multithreading,user-interface,C#,Multithreading,User Interface,我想我现在在逻辑上有些问题 我使用阻塞集合对其他PC进行线程安全调用。通常情况下,它是这样的: public class MyClass { private BlockingCollection<workUnit> workUnits = new BlockingCollection<workUnit>(); public void EnQueue(workUnit item) { workUnits.Add(item); } privat
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);
}
}
}
公共类MyClass
{
私有BlockingCollection工作单元=新建BlockingCollection();
公共无效排队(工作单元项)
{
工作单元。添加(项);
}
私有无效出列()
{
而(!stopFlag)
{
workUnit项=workUnits.Take();
多龙宁凝灰岩(工作单元);
}
}
}
现在,我想将其可视化给用户
用户应该看到这一点
private async void btnAddItem_Click(object sender, EventArgs e)
{
var item = new workUnit();
// TODO: Add item on UI here
try
{
await myClass.EnQueue(item);
// TODO: Update UI with success result here (no context synchronisation is needed here it is already in the UI context)
}
catch
{
// TODO: Update UI with error result here (no context synchronisation is needed here it is already in the UI context)
}
}
使用网格向用户显示项目
有没有一个简单的解决方案或方法来可视化正在发生的事情?我将尝试这样做:
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();
item.SetState("Processing Started");
try
{
DoLongRunningDBStuff(workUnit);
item.SetState("Processing Successful");
}
catch
{
item.SetState("Processing Failed");
}
}
}
}
如果您使用.NET4.5,您将能够使用在UI线程上下文中自动同步任务继续的功能。例如,在调用方一侧的中(假设它是在UI线程上启动的),您只需执行以下操作:
private async void btnAddItem_Click(object sender, EventArgs e)
{
var item = new workUnit();
// TODO: Add item on UI here
try
{
await myClass.EnQueue(item);
// TODO: Update UI with success result here (no context synchronisation is needed here it is already in the UI context)
}
catch
{
// TODO: Update UI with error result here (no context synchronisation is needed here it is already in the UI context)
}
}
在这两个示例中,您甚至不需要任何锁定,只需要将更新发布到正确的上下文中(在上一个示例中,甚至不需要显式更新,编译器会为您处理)这是一个非常严重的阻抗不匹配,BlockingCollection是一个在线程代码中使用的类。UI从根本上说是线程不安全的。还有一个严重的风险,就是代码的速度会急剧减慢。最好不要这样做,真的。这是一个用户永远不必担心的实现细节。@Hans:它主要不是显示内部实现细节。{总是忘记不要使用enter herer)想想下面的用例:数据发送到多台电脑。这通常需要约150毫秒,但也可能需要3秒钟。在以前的产品中,有一个状态行显示数据已发送。因此,用户习惯并期望后继者也会显示信息,并且他们在e他们可以看到,什么没有成功发送,并且可以手动触发重新发送。前者用于用户反馈实际发生的事情。后者用于用户交互。例如,用于添加值,即某人可以重复失败的作业,或者可以查找失败的原因(机器停机,另一方有错误的版本,双方都更改了数据,他们必须确认哪一个是正确的,等等。)Hi,.net 4.0或4.5可以,但作业通常不是由ui线程初始化的,而是由后台线程初始化的。因此我认为“等待”不是解决方案。有n个线程可以为任务提供数据,但通过连接,一次只能运行一个线程。因此,我使用了同步方法dolongrunningstuff的入队和出队。(好的,类有多个实例,但每个客户端只有一个实例)。我的问题主要是如何发出信号表示该对象已添加。不是workUnits。添加(项);后跟item.SetState not threadsafe?@Offler无论任务是由后台线程还是UI本身启动,都不意味着UI不能等待创建的任务。此外,任务不必由n个线程处理。您可以使用在中找到的一个调度程序在单个线程上执行任务(按照创建顺序)。