我即將編寫一個從TCP端口獲取流數據的應用程序,對它們進行一些實時計算。到目前爲止,所有這一切都很好,但是當生產者線程開始在數據塊上進行一些打包時(參見代碼),用戶界面和選取框進度條會卡住(對於不規則的短時間段)。UI線程被快速使用BlockingCollection卡住了?
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在流式傳輸過程中顯示CPU使用率爲100%,每個塊包含大約2000個浮點值,其中4個或5個每秒都在沖刷一次。我也禁用了Logger,但沒有效果。消費者和評估線程被禁用。
除了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] =新線程(產生); myThreads [0] .Name =「Produce」; myThreads [0]。開始();」
目前還不清楚您發佈的代碼在哪裏運行,或者您實際發生了哪些線索...請澄清您的情況。 –
add方法似乎有點奇怪,但塊必須每個確實有500個val,並且必須保持連接到它們的通道,這很難通過大量數據保證。除此之外,出於性能原因,我不會想要使用刪除字典或BC,因爲它非常昂貴,所以我更新而不是刪除和添加。但添加方法不是問題,只要生產者不訪問BlockingCollection'bcPort',它就運行得非常流暢和快速。 – Rome