Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何可视化blockingcollection_C#_Multithreading_User Interface - Fatal编程技术网

C# 如何可视化blockingcollection

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

我想我现在在逻辑上有些问题

我使用阻塞集合对其他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);
    }
  }
} 
公共类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)
        }
    }
    
    使用网格向用户显示项目

  • 如果项已排队,则将其添加到工作单元中,并添加到绑定到数据网格的列表中
  • 如果项目已退出队列(已使用),则更新网格列表中的项目
  • 令人头痛的是,如何使这个线程安全,以及哪些部分需要线程安全

    若我把一些需要时间的东西放在工作单元后面,我认为这是可能的,那个么数据会变得复杂

    这样做可行吗

  • 如果项已排队,则将其添加到workunits和UI的附加BlockingCollection
  • 如果项目已退出队列,请在2上尝试设置。BlockingCollection并将其删除,更新状态并再次将其附加到第二个列表
  • 我需要在1号和2号上加一把锁吗?如果是这样,它是否会完全阻止add If等待Take


    有没有一个简单的解决方案或方法来可视化正在发生的事情?

    我将尝试这样做:

    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个线程处理。您可以使用在中找到的一个调度程序在单个线程上执行任务(按照创建顺序)。