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는 스트리밍 중 100 % CPU 사용량을 보여 주며, 청크에는 약 2000 개의 부동 값이 있고 그 중 4 개 또는 5 개는 초당 돌진합니다. 나는 또한 로거를 무효로했지만 효과는 없었다. 소비자 및 평가 스레드는 사용할 수 없습니다.
ui 스레드 외에도 "ReceiveAndSave"라는 스레드 만 들어오는 float 값에서 청크를 만듭니다 (코드, 메서드 "추가"참조). 스레드 "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 = "제작"; myThreads [0] .Start(); '
게시 한 코드가 어디에서 실행되고 있는지 또는 실제로 어떤 스레드에서 진행되고 있는지 명확하지 않습니다 ... 상황을 명확히하십시오. –
add 메소드는 다소 이상하게 보일 것입니다.하지만 청크는 정확히 각각 500 개의 val을 가져야하고, 채널에 연결되어 있어야합니다. 그렇게 많은 데이터가 쇄도하는 것은 쉽지 않습니다. 성능상의 이유로, 나는 그렇지 않습니다. 왜냐하면 그 값이 비싸기 때문에 사전이나 기원전의 제거를 사용하고 싶습니다. 그래서 나는 제거하고 추가하는 대신에 업데이트하고 있습니다. 그러나 add 메소드가 문제가 아니며 제작자가 BlockingCollection 'bcPort'에 액세스하지 않는 한 매우 부드럽고 빠릅니다. – Rome