Search code examples
c#measurement-studio

Measurement studio graphs, Collection was modified exception


I have a problem with graphic (I have few instance of this class) of measurement studio dll. after a few occurences i get Collection was modified; enumeration operation may not execute. but the exception is unhandled so I can't see exactly where it's happening. I red on internet it's because I don't feed the graph in UI thread, but I think I'm not outside of the UI thread :

private delegate void del(double press, double temp, double press1);
private object graphic_mutex = new object();
private void UpdateView(double press, double temp, double press1)
{
    if (InvokeRequired)
        Invoke(new del (UpdateView), new object[] { press , temp, press1});
    lock (graphic_mutex)
    {
        _PressionLine.PlotYAppend(press);
        _TemperatureLine.PlotYAppend(temp);
        if (_isdoublePressureSensor == true)
            _PressionLine2.PlotYAppend(press1);
    }
}

Exact error i get :

Exception thrown: 'System.InvalidOperationException' in mscorlib.dll
An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll
Collection was modified; enumeration operation may not execute.

Do you have any idea to solve this issue ?


Solution

  • You should return after the invoke. You don't want the code to be executed twice when an InvokeRequired is true. Either the code can be executed directly or should be executed by an invoke. Not both.

    private delegate void del(double press, double temp, double press1);
    private object graphic_mutex = new object();
    private void UpdateView(double press, double temp, double press1)
    {
        if (InvokeRequired)
        {
            Invoke(new del (UpdateView), new object[] { press , temp, press1});
            return;
        }
        
        lock (graphic_mutex)
        {
            _PressionLine.PlotYAppend(press);
            _TemperatureLine.PlotYAppend(temp);
            if (_isdoublePressureSensor == true)
                _PressionLine2.PlotYAppend(press1);
        }
    }
    

    The lock should not be needed, because it will(must be) always be executed on the UI thread.