简体   繁体   中英

WCF Duplex client idle wont update userinterface

I have clients thats is connected to a duplex wcf service 24/6 it is restarted every sunday. In the client iam using a listview to display some information. The listview itemssource is binded to a custom ObservableCollection. The client is calling a keepalive method every minute to the wcf service.

My problem here is the client works fine when there is activity in the client. But when there is no activity and the application just run the keepalive method for about 10-16 hours. And iam trying to add and remove data to the listview it seems that nothing works. But the wcf service logging the method add and remove is working fine. Its like the userinterface isnt updating. When i restart the application everything works fine.

how do i solve this problem ?

My custom ObservableCollection object code :

    public class ObservableOrderResponseQueue : INotifyCollectionChanged, IEnumerable<OrderResponse>
{
    public event NotifyCollectionChangedEventHandler CollectionChanged = (o, e) => { };
    private List<OrderResponse> _list = new List<OrderResponse>();

    /// <summary>
    /// Adds to the list.
    /// </summary>
    /// <param name="orderResponse">OrderResponse.</param>
    public void Add(OrderResponse orderResponse)
    {
        //Only 6 items in list is possible if more then 6 remove the first item.
        if (_list.Count >= 6)
        {
            RemoveAt(0);
        }

        this._list.Add(orderResponse);            

        CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, orderResponse, (_list.Count - 1)));
    }

    /// <summary>
    /// Remove from list.
    /// </summary>
    /// <param name="index">Item index to remove.</param>
    public void RemoveAt(int index)
    {
        OrderResponse order = this._list[index];
        this._list.RemoveAt(index);

        CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, order, index));
    }

    /// <summary>
    /// Remove from list.
    /// </summary>
    /// <param name="orderResponse">Item to be removed.</param>
    public void Remove(OrderResponse orderResponse)
    {
        if (_list.Count == 0) return;

        var item = _list.Where(o => o.OrderDetail.TrayCode == orderResponse.OrderDetail.TrayCode).FirstOrDefault();
        int index = _list.IndexOf(item);

        if (index == -1) return;

        CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));

        this._list.RemoveAt(index);
    }

    #region IEnumerable<OrderResponse> Members

    public IEnumerator<OrderResponse> GetEnumerator()
    {
        return _list.GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    IEnumerator IEnumerable.GetEnumerator()
    {
        return _list.GetEnumerator();
    }

    #endregion


}

Here is how i bind the usercontrol to the class.

            //Set up client callbacks events
        App.clientBack.ClientNotified += new ClientNotifiedEventHandler(clientBack_ClientNotified);
        App.clientBack.AddToDisplayEvent += new AddToDisplayEventHandler(clientBack_AddToDisplayEvent);
        App.clientBack.RemoveFromDisplayEvent += new RemoveFromDisplayEventHandler(clientBack_RemoveFromDisplayEvent);
        App.clientBack.UpdateQueueDisplayEvent += new UpdateQueueDisplayEventHandler(clientBack_UpdateQueueDisplayEvent);


        //Show one chair or many.
        if (_settings.IsOneChair)
        {
            userControlOneChair.ItemSource = _queueProductionItems;
        }
        else
        {
            userControlChairs.ItemsSource = _queueProductionItems;
        }

Remove and add methods

        void clientBack_RemoveFromDisplayEvent(object sender, RemoveFromDisplayEventArgs e)
    {
        try
        {
            _logger.Info("Remove from display.");

            userControlChairs.Dispatcher.Invoke((Action)(() =>
            {
                _queueProductionItems.Remove(e.OrderResponse);
            }));
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    void clientBack_AddToDisplayEvent(object sender, AddToDisplayEventArgs e)
    {
        try
        {
            _logger.Info("Add to display.");

            userControlChairs.Dispatcher.Invoke((Action)(() =>
            {
                _queueProductionItems.Add(e.OrderResponse);
            }));
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

Thanks for help!

What i did was implementing a Heartbeat mechanism. And it all worked out.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM