我在FFTCalculated事件中有一个循环,它从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);
答案 0 :(得分:0)
从评论中将所有内容放在一起,您的代码应如下所示:
使用FFTWriter的代码:
private FFTWriter _writer;
private void StartNewFFT()
{
_writer = new FFTWriter(path);
}
private void FftCalculated(object sender, FftEventArgs e)
{
_writer.WriteValues(e.Result);
}
FFTWriter类中的代码
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));
}
编辑:我将代码更改为仅使用FFTWriter的一个实例,并将外部foreach从使用代码移动到DoWork()方法中,以便在工作线程中执行。