I am about to write an application that gets streaming data from the TCP port, doing some real time calculations on them. All good so far, but the user interface and the marquee progress bar are getting stuck (for irregular, short time periods) when the producer thread is started to do some packaging on the data chunks (see code).
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());
}
}
I did a lot of testing and found out that the access to the BlockingCollection bcPort seems to be the problem. bcPort gets constantly chunks from another data-adder thread which is also supposed not to influence the ui thread. So I don't understand the following:
1.) Why is the GUI getting stuck when I am using different threads for adding and packaging the chunks?
2.) Why is this happening when I am using a BC for storing data? Aren't these thread safe collections for this certain purpose?
By the way: Windows 7 ResourceManager shows 100% CPU usage during streaming, the chunks contain about 2000 float values each, 4 or 5 of them a rushing in per second. I also disabled the Logger but no effect. The consumer and evaluation threads are disabled.
Besides the ui thread, there is only a thread called "ReceiveAndSave" which makes chunks out of incoming float values (see code, Method "Add"). the thread "Producer" is doing some further packaging and enqueues the chunks for the consumer (deactivated).
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);
}
}
The producer is started with 'myThreads[0] = new Thread(Produce); myThreads[0].Name = "Produce"; myThreads[0].Start();'