应用程序在获取FFT结果时挂起

本文关键字:挂起 结果 FFT 获取 应用程序 | 更新日期: 2023-09-27 18:01:33

我在fftcalculate事件内部有一个循环,该事件从FFT应用于原始数据后获得复杂值。

基类

 private void FftCalculated(object sender, FftEventArgs e)
    {
        writer = new FFTWriter(path);
            foreach (var a in e.Result)
                writer.WriteValues(a.X,a.Y);  
    }

因为它在UI线程中我想把它移到后台线程中。因此,我创建了一个并发队列,并将两个值X和Y放入队列,并将它们写入一个文本文件。

 private ConcurrentQueue<Tuple<double?, double?>> _queue = new ConcurrentQueue<Tuple<double?,double?>>();
    private string _filePath;
    private Thread _workerThread;
    private bool _isDisposed;
    private void DoWork()
    {
        while (!_isDisposed)
        {
            Tuple<double?, double?> values;
            if (_queue != null && _queue.TryDequeue(out values))
            {
                if(File.Exists(_filePath))
                    try
                    {
                        File.AppendAllText(_filePath, values.Item1 + "," + values.Item2);
                    }
                    catch (Exception ex) { ex.ToString(); }
            }
        }
    }
    public void Dispose()
    {
        if (!_isDisposed)
        {
            _isDisposed = true;
            _workerThread.Join();
        }
    }
    public FFTWriter(string filePath)
    {
        _filePath = filePath;
        _workerThread = new Thread(DoWork);
        _workerThread.Start();
    }
    public void WriteValues(double? v1, double? v2)
    {
        if (v1.HasValue == true && v2.HasValue == true)
        _queue.Enqueue(new Tuple<double?,double?>(v1.Value, v2.Value));
    }

但是,应用程序仍然挂起。我做错了什么?我认为问题在这里,因为循环在主线程中运行。我怎么解决这个问题?

 foreach (var a in e.Result)
                writer.WriteValues(a.X,a.Y);

应用程序在获取FFT结果时挂起

把这些注释放在一起,你的代码应该是这样的:

使用fftwwriter的代码:

private FFTWriter _writer;
private void StartNewFFT()
{
    _writer = new FFTWriter(path);
} 
private void FftCalculated(object sender, FftEventArgs e)
{
    _writer.WriteValues(e.Result);  
}

fftwwriter类

中的代码
private BlockingCollection<IEnumerable<FFTResult>> _queue = new BlockingCollection<IEnumerable<FFTResult>>();
private string _filePath;
private Thread _workerThread;
private bool _isDisposed;
private void DoWork()
{
    if(_queue == null)
        return;
    if(!File.Exists(_filePath))
        return;
    using(var file = File.Open(_filePath))
    {
        foreach(var results in _queue)
        {
           try
           {
               foreach(var values in results)
               {
                   if (values.X.HasValue == true && values.Y.HasValue == true)
                       file.WriteLine($"{values.X},{values.Y}");
               }
           }
            catch (Exception ex) { ex.ToString(); }
           }
        }
    }
}
public void Dispose()
{
    if (!_isDisposed)
    {
        _queue.CompleteAdding();
        _isDisposed = true;
        _workerThread.Join();
    }
}
public FFTWriter(string filePath)
{
    _filePath = filePath;
    _workerThread = new Thread(DoWork);
    _workerThread.Start();
}
public void WriteValues(IEnumerable<FFTResult> results)
{
    _queue.Add(new Tuple<double?,double?>(v1.Value, v2.Value));
}

EDIT:我更改了代码,仅使用fftwwriter的一个实例,并将外部foreach从使用代码移动到DoWork()方法中,因此它在工作线程中执行。