我即将编写一个从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个是每秒冲入。我也禁用了Logger但没有效果。消费者和评估线程被禁用。
除了ui线程之外,只有一个名为“ReceiveAndSave”的线程,它使传入的浮点值产生块(参见代码,方法“添加”)。线程“生产者”正在进行一些进一步的打包并将消费者的块排入队列(停用)。
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 =“Produce”; myThreads [0]。开始();'
答案 0 :(得分:1)
它确实卡住了,你只是在做太多工作。这使得它不再处理其低优先级任务,响应输入和绘制通知。这确实使它看起来就像它被卡住一样,你的用户肯定会这么认为。
关键是只以对人眼有意义的速度更新UI。除了每秒超过25次更新的模糊之外,它无法感知任何东西。如果您将其推送到每秒多达一千次更新,您将获得您描述的行为。因此,收集结果,并且在足够的时间到期之前不要调用/更新。通常将您显示的信息压缩为可消耗的块,以便为用户提供有意义的反馈,列表显示数百个新项目,一秒钟对任何人都没用。