应用程序在获取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);
把这些注释放在一起,你的代码应该是这样的:
使用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()方法中,因此它在工作线程中执行。