D3绘图仪和文件观察器,干扰?

时间:2013-03-05 21:21:45

标签: c# wpf events filesystemwatcher dynamic-data-display

我正在使用文件监视器监视文件输出,然后使用d3(动态数据显示)动态显示结果。这是更多细节:

  1. 数据是一系列快速生成的tiff文件(每个文件生成20-25毫秒);
  2. 一旦有文件进入,就会触发事件,并处理文件(某些统计数据计算);
  3. 结果将发送到d3绘图仪,它将在章程中动态显示结果。
  4. 当我关闭d3包机窗口时,文件监视器捕获器几乎所有事件,但这是我的问题:

    • 但是,当我打开d3包机窗口时,即使没有任何统计数据计算,文件观察者也会丢弃很多事件(发生一些大的差距)。

    以下是我们尝试的内容:

    • 增加观察者缓冲区,但只要d3包机窗口打开,它仍然会丢弃事件。
    • 使用C ++ dll计算统计数据,但看起来更慢。

    所以我想知道:

    • d3绘图仪和文件观察者是否发生冲突/相互干扰?
    • 我可以将它们一起用于实时情节吗?
    • 无论如何都可以解决我的问题?

    任何指针都表示赞赏。

    这是d3绘图仪的代码,包括构造函数,绘图仪启动器和绘图仪更新:

    #region Constructor
    public SignalStatsDisplay()
    {
        InitializeComponent();
    
        //   timeDomainPlotter.Legend.Remove();
    
        _initialChildrenCount = timeDomainPlotter.Children.Count;
    
        int count = timeDomainPlotter.Children.Count;
    
        //do not remove the initial children
        if (count > _initialChildrenCount)
        {
            for (int i = count - 1; i >= _initialChildrenCount; i--)
            {
                timeDomainPlotter.Children.RemoveAt(i);
            }
        }
    
        _nMaxStatsOneChannel = Enum.GetNames(typeof(Window1.ROISignalList)).Length;
        _curveBrush = new Brush[_nMaxStatsOneChannel];
        _statsEnable = new int[_nMaxStatsOneChannel];
    
        for (int i = 0; i < _nMaxStatsOneChannel; i++)
        {
            _curveBrush[i] = new SolidColorBrush((Color)ColorConverter.ConvertFromString(_colorList[i]));
            _statsEnable[i] = 0;
        }
    
        _nActiveStatsOneChannel = 0;
    }
    #endregion Constructor
    
    public void InitiateSignalAnalysisPlot()
    {
        _statsName = Enum.GetNames(typeof(Window1.ROISignalList));
    
        int count = 0;
        _statsEnableIndex = new int[_nActiveStatsOneChannel];
        for (int i = 0; i < _nMaxStatsOneChannel; i++)  // assign color
        {
            if (_statsEnable[i] == 1)
            {
                _statsEnableIndex[count] = i;
                count++;
            }
        }
    
    
    
        if (_nActiveChannel > 0)    // timeDomainPlotter init
        {
            _dataX = new List<double[]>();
            _dataY = new List<double[]>();
    
            double[] dataXOneCh = new double[_signalLength];
            double[] dataYOneCh = new double[_signalLength];
    
            dataXOneCh[0] = 0;
            dataYOneCh[0] = 0;
    
            for (int i = 0; i < _nActiveChannel; i++)
            {
                for (int j = 0; j < _nActiveStatsOneChannel; j++)
                {
                    _dataX.Add(dataXOneCh);    // data x-y mapping init
                    _dataY.Add(dataYOneCh);
    
                    EnumerableDataSource<double> xOneCh = new EnumerableDataSource<double>(dataXOneCh);
                    EnumerableDataSource<double> yOneCh = new EnumerableDataSource<double>(dataYOneCh);
    
                    xOneCh.SetXMapping(xVal => xVal);
                    yOneCh.SetXMapping(yVal => yVal);
    
                    CompositeDataSource dsOneCh = new CompositeDataSource(xOneCh, yOneCh);
    
                    LineAndMarker<MarkerPointsGraph> lam = timeDomainPlotter.AddLineGraph(dsOneCh,
                        new Pen(_curveBrush[_statsEnableIndex[j]], 2),
                        new CirclePointMarker { Size = 5, Fill = _curveBrush[_statsEnableIndex[j]] },
                        new PenDescription(_statsName[_statsEnableIndex[j]]));
    
                }
            }
    
            Action FitToView = delegate()
            {
                timeDomainPlotter.FitToView();
            };
            this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, FitToView);
        }
        else
        {
            return;
        }
    }
    
    public void RedrawSignalAnalysisPlot()
    {
        int startIndex = _initialChildrenCount;
    
        if ((_nActiveStatsOneChannel > 0) && (_dataX != null) && (_dataY != null))
        {
            CompositeDataSource[] dsCh = new CompositeDataSource[_nActiveStatsOneChannel];
            int m, n;
            int index;
    
            for (int i = 0; i < _nActiveChannel; i++)
            {
                for (int j = 0; j < _nActiveStatsOneChannel; j++)
                {
                    index = i * _nActiveStatsOneChannel + j;
                    if (_dataX[index].Length == _dataY[index].Length)
                    {
                        EnumerableDataSource<double> xOneCh = new EnumerableDataSource<double>(_dataX[index]);
                        xOneCh.SetXMapping(xVal => xVal);
                        EnumerableDataSource<double> yOneCh = new EnumerableDataSource<double>(_dataY[index]);
                        yOneCh.SetYMapping(yVal => yVal);
                        CompositeDataSource ds = new CompositeDataSource(xOneCh, yOneCh);
    
                        Action UpdateData = delegate()
                        {
                            m = i * 2;
                            n = j * 2;
    
                            // ((LineGraph)timeDomainPlotter.Children.ElementAt(startIndex + n + m * _nActiveStatsOneChannel)).DataSource = ds;
                            // ((LineGraph)timeDomainPlotter.Children.ElementAt(startIndex + n + m * _nActiveStatsOneChannel)).LinePen
                            //    = new Pen(new SolidColorBrush(_curveBrush[j]), 1);
    
                            ((MarkerPointsGraph)timeDomainPlotter.Children.ElementAt(startIndex + n + 1 + m * _nActiveStatsOneChannel)).DataSource = ds;
                            //  ((MarkerPointsGraph)timeDomainPlotter.Children.ElementAt(startIndex + n + 1 + m * _nActiveStatsOneChannel)).Marker
                            //      = new CirclePointMarker { Size = 5, Fill = Brushes.Green };
                        };
    
                        this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, UpdateData);
                    }
    
                }
    
    
            }
    
            /* Action PlotFitToView = delegate()
              {
                  timeDomainPlotter.FitToView();
              };
    
             this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, PlotFitToView);*/
        }
    }
    

    以下是监控文件的方式: 提交事件(文件已写入)

    void tiffWatcher_EventChanged(object sender, WatcherExEventArgs e)
    {
        string fileName = ((FileSystemEventArgs)(e.Arguments)).FullPath;
        string fileExt = StringExtension.GetLast(fileName, 4);
    
        if (!IsFileLocked(fileName))
        {
    
            Action EventFinished = delegate()
            {
                CreateListViewItem(fileName, "Finished", DateTime.Now.ToString("HH:mm:ss.fff"));
            };
    
            listView1.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, EventFinished);
    
            _tiffName.Add( fileName);
            _tiffFilledCount++;    
        }
    }
    

    tiff数据处理,以及与d3绘图仪的数据通信:

    void tiffTimer_Tick(object sender, EventArgs e)
    {
        //throw new NotImplementedException();
        byte[] image = new byte[_signalManager.ImgWidth * _signalManager.ImgHeight];
    
        if (_tiffFilledCount - _tiffProcessedCount >= 1)
        {
    
    
            string fileName = _tiffName[_tiffProcessedCount++];
            char filePre = fileName[49];
            int indexBeigin = fileName.LastIndexOf("_");
            int indexEnd = fileName.LastIndexOf(".");
    
            _signalIndex = Convert.ToInt32(fileName.Substring(indexBeigin + 1, indexEnd - indexBeigin - 1)) - 1; // 0 based//
            _deltaT = ExtractTiffDeltaT(fileName, "DeltaT=", 1);
            _channelIndex = (int)Enum.Parse(typeof(ChannelList), Convert.ToString(filePre));
            TIFFIImageIO.LoadTIFF(fileName, ref image);
            _signalManager.Image = image;
            for (int i = 0; i < _nActiveStatsOneChannel; i++)
            {
                _signalManager.GetSignal( _signalDisplay.StatsEnableIndex[i], ref _signal);
                UpdateSignal(_channelIndex, i, _tiffProcessedCount-1, _deltaT, _signal);
            }
    
          // if( _tiffProcessedCount % 5 == 0)
            _signalDisplay.SetData(_XList, _YList, true);
        }
    }
    

    我使用Timer.Tick每50-100毫秒处理一次文件,仍然在测试。

1 个答案:

答案 0 :(得分:0)

我处理它的方法是设置一个Timer,循环处理计算,显示。到目前为止,它工作正常。当然会有很多事件丢失,但是我们处理了大量的点数(数千个),因此可以通过数百个来完成绘图。这是代码:

private Timer _tiffTimer;
void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            //throw new NotImplementedException();
            _tiffTimer = new Timer();
            _tiffTimer.Interval = 50;  // change interval to change performance
            _tiffTimer.Tick += new EventHandler(tiffTimer_Tick);
            _tiffTimer.Start();

        }

void tiffTimer_Tick(object sender, EventArgs e)
        {
            //do your stuff here

        }