C#刷新datagridview或listview中的websocket实时异步数据

C#刷新datagridview或listview中的websocket实时异步数据,c#,listview,asynchronous,websocket,datagridview,C#,Listview,Asynchronous,Websocket,Datagridview,首先,我要说的是,我是一名初学C#的程序员,有大约6个月的经验。我可能不会遵循最佳实践,但我渴望学习。:) 我正在构建一个小应用程序,显示我在交易所进行的所有订单和交易。此exchange提供了一个WebSocket服务器,我可以成功订阅该服务器。数据正在进入,我可以成功地将其排队并同步处理。在我的应用程序中,我有一个DataGridView,其绑定源链接到它。此DataGridView需要显示所有未结订单。当订单被填写时,它必须从列表中消失,当我打开一个新订单时,它应该显示在列表中。非常基本

首先,我要说的是,我是一名初学C#的程序员,有大约6个月的经验。我可能不会遵循最佳实践,但我渴望学习。:)

我正在构建一个小应用程序,显示我在交易所进行的所有订单和交易。此exchange提供了一个WebSocket服务器,我可以成功订阅该服务器。数据正在进入,我可以成功地将其排队并同步处理。在我的应用程序中,我有一个DataGridView,其绑定源链接到它。此DataGridView需要显示所有未结订单。当订单被填写时,它必须从列表中消失,当我打开一个新订单时,它应该显示在列表中。非常基本

这是我有生以来第一次使用MVP模式。更新标签很容易,但是管理DataGridView我发现有点复杂。我想知道什么是拥有总是最新的DataGridView的最佳方式

我的表格:

public partial class MTMainForm : Form, IMTMainForm
{
  public BindingSource bSRCOrders
  {
    get => (BindingSource)dGVOrders.DataSource;
    set => SetBindingSRC(dGVOrders, value); //dGVOrders = DataGridView
  }

  private void SetBindingSRC(DataGridView dgv, BindingSource bs)
  {
    if (dgv.DataBindings.Equals(bs))
      return;

    if (!InvokeRequired)
    {
      dgv.DataSource = bs;
        return;
    }

    this.Invoke(new Action(() =>
    {
      dgv.DataSource = bs;
    }));
  }
}
接口:

interface IMTMainForm
{
  BindingSource bSRCOrders { get; set; }
}
我有一个演示者课程:

class MTMainPresenter
{
  private readonly IMTMainForm _view;

  private void Subscribe(WebsocketClient wsc) 
  {
    client.Streams.OrderStream
      .Select(ordr => 
        Observable.FromAsync(async () => {
          HandleOrderResponse(ordr);
        }))
      .Concat() //All incoming orders are queued and that is the way I want it.
      .Subscribe();
  }

  private void HandleOrderResponse(OrderResponse response)
  {
    switch (response.Action)
    {
      case ExchAction.Insert:
        ??
        break;
      case ExchAction.Delete:
        ??
        break;
      case ExchAction.Update:
        ??
        break;
    }
  }
}
我需要的是一些在DataGridView中插入、删除和搜索/更新数据的建议,以便我的列表始终表示我在exchange上的订单状态

提前感谢你的帮助。 保罗(我明白了!)

我的表格:

public partial class MTMainForm : Form, IMTMainForm
{
  public BindingSource bSRCOrders
  {
    get => (BindingSource)dGVOrders.DataSource;
    set => SetBindingSRC(dGVOrders, value); //dGVOrders = DataGridView
  }

  private void SetBindingSRC(DataGridView dgv, BindingSource bs)
  {
    //if (dgv.DataBindings.Equals(bs))   --> Commented this
    //  return;                          --> Commented this

    if (!InvokeRequired)
    {
      dgv.DataSource = bs;
      ((BindingSource)dgv.DataSource).ResetBindings(false); // Add this to refresh DGV
      return;
    }

    this.Invoke(new Action(() =>
    {
      dgv.DataSource = bs;
      ((BindingSource)dgv.DataSource).ResetBindings(false); // Add this to refresh DGV
    }));
  }
}
我还添加了一个计时器,用于刷新绑定源。我还得检查一下这是否仍然有必要

我用维护的列表创建了一个新类。我还添加了一个方法,将列表转换为BindingSource,用于替换现有的BindingSource

class OrdersStatsHandler
{
    private readonly List<Order> _orderList = new List<Order>();

    public void HandleOrder(Order newOrder)
    {
        List<string> removeList = new List<string>() { newOrder.OrderId };

        switch (newOrder.OrdStatus)
        {
            case OrderStatus.Rejected:
            case OrderStatus.Filled:
            case OrderStatus.Canceled:
                _orderList.RemoveAll(r => removeList.Any(a => a == r.OrderId));
                break;
            case OrderStatus.New:
            case OrderStatus.PartiallyFilled:
                if (_orderList.Where(o => o.OrderId == newOrder.OrderId).Count() == 0)
                    _orderList.Add(newOrder);
                else
                {
                    _orderList.RemoveAll(r => removeList.Any(a => a == r.OrderId));
                    _orderList.Add(newOrder);
                }
                break;
        }
    }

    public BindingSource GetBindingSource()
    {
        BindingSource bs = new BindingSource();
        bs.DataSource = _orderList;
        return bs;
    }
} 
不客气!:)

class MTMainPresenter
{
    private readonly IMTMainForm _view;
    private OrdersStatsHandler _orderStatsHandler;

    private void Subscribe(WebsocketClient wsc)
    {
        client.Streams.OrderStream
          .Select(ordr =>
            Observable.FromAsync(async () => {
                HandleOrderResponse(ordr);
            }))
          .Concat() //All incoming orders are queued and that is the way I want it.
          .Subscribe();
    }

    private void HandleOrderResponse(OrderResponse response)
    {
        try
        {
            foreach (Order o in response.Data)
            {
                _orderStatsHandler.HandleOrder(o);
            }

            var bs = _orderStatsHandler.GetBindingSource();
            _view.bSRCOrders = bs;
        }
        catch (Exception exc)
        {
            Log.Error(exc.Message);
        }
    }
}