我即将编写一个从 TCP 端口获取流数据的应用程序,并对它们进行一些实时计算。到目前为止一切都很好,但是当生产者线程开始对数据块进行一些打包(参见代码)时,用户界面和选框进度条会卡住(对于不规则的短时间段)。
void Produce()
{
try
{
while (true)
{
foreach (Chunk _chunk in bcPort)
{
if (_ThreadCanceler.IsCancellationRequested) break;
Chunk chunk = bcPort.Take();
chunk.TimeTracker = new Stopwatch();
chunk.SegmentId = iSegmentId;
if (chunk.Channel + 1 == iChannels) iSegmentId++; // last channel, raise segment id.
iPrevChannel = chunk.Channel;
// _ProcessAndJoin.EnqueueTask(chunk, _ThreadCanceler);
iChunksProduced++;
_LogWriter.WriteMessage("Task " + Task.CurrentId.ToString() + "(producer): ADDED_ Chunk[" + chunk.Channel + ":" + chunk.Vals.Count.ToString() + ":" + chunk.SegmentId + "] [" + iChunksProduced + "]. " + bcPort.Count + " for takeaway. Thread: " + Thread.CurrentThread.ManagedThreadId.ToString());
}
if (_ThreadCanceler.IsCancellationRequested) break;
}
}
catch (Exception ex)
{
Console.WriteLine("ForkAndCrate.cs: Produce(): " + ex.ToString());
}
}
我做了很多测试,发现对 BlockingCollection bcPort 的访问似乎是问题所在。bcPort 不断从另一个数据加法器线程获取块,该线程也应该不会影响 ui 线程。所以我不明白以下内容:
1.) 当我使用不同的线程来添加和打包块时,为什么 GUI 会卡住?
2.) 为什么在我使用 BC 存储数据时会发生这种情况?这些线程安全集合不是为了这个特定目的吗?
顺便说一句:Windows 7 ResourceManager 在流式传输期间显示 100% 的 CPU 使用率,每个块包含大约 2000 个浮点值,其中 4 或 5 个每秒涌入。我也禁用了记录器,但没有效果。消费者和评估线程被禁用。
除了 ui 线程,只有一个名为“ReceiveAndSave”的线程从传入的浮点值中生成块(参见代码,方法“Add”)。线程“Producer”正在做一些进一步的打包并将消费者的块排入队列(停用)。
public void Add(short iChannel, float fValue)
{
try
{
_Benchmark.UpdateRec(); // one value received, update benchmark:
if (!cdBasin[iChannel].Enqueue(fValue))
{
Chunk chunk = new Chunk();
chunk.Vals = cdBasin[iChannel].ToListDeep;
chunk.Channel = iChannel;
bcPort.Add(chunk);
cdBasin.AddOrUpdate(iChannel, new BoundedQueue<float>(iSegmentSizePerChannel), (key, oldValue) => new BoundedQueue<float>(iSegmentSizePerChannel));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Stop", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
}
生产者以 'myThreads[0] = new Thread(Produce); 开始 myThreads[0].Name = "生产"; myThreads[0].Start();'