【发布时间】:2011-05-03 11:31:11
【问题描述】:
我最近开始了我的第一个多线程代码,我很感激一些 cmets。
它从缓冲区提供视频样本,该缓冲区由流解析器在后台填充(不在本问题的范围内)。如果缓冲区为空,则需要等到缓冲区级别变得可以接受后再继续。
代码适用于 Silverlight 4,删除了一些错误检查:
// External class requests samples - can happen multiple times concurrently
protected override void GetSampleAsync()
{
Interlocked.Add(ref getVideoSampleRequestsOutstanding, 1);
}
// Runs on a background thread
void DoVideoPumping()
{
do
{
if (getVideoSampleRequestsOutstanding > 0)
{
PumpNextVideoSample();
// Decrement the counter
Interlocked.Add(ref getVideoSampleRequestsOutstanding, -1);
}
else Thread.Sleep(0);
} while (!this.StopAllBackgroundThreads);
}
void PumpNextVideoSample()
{
// If the video sample buffer is empty, tell stream parser to give us more samples
bool MyVidBufferIsEmpty = false; bool hlsClientIsExhausted = false;
ParseMoreSamplesIfMyVideoBufferIsLow(ref MyVidBufferIsEmpty, ref parserAtEndOfStream);
if (parserAtEndOfStream) // No more data, start running down buffers
this.RunningDownVideoBuffer = true;
else if (MyVidBufferIsEmpty)
{
// Buffer is empty, wait for samples
WaitingOnEmptyVideoBuffer = true;
WaitOnEmptyVideoBuffer.WaitOne();
}
// Buffer is OK
nextSample = DeQueueVideoSample(); // thread-safe, returns NULL if a problem
// Send the sample to the external renderer
ReportGetSampleCompleted(nextSample);
}
代码似乎运行良好。但是,有人告诉我使用 Thread.Wait(...) 是“邪恶的”:当没有请求样本时,我的代码会不必要地循环,占用 CPU 时间。
我的代码可以进一步优化吗?由于我的课程是为需要样本的环境设计的,潜在的“无意义循环”场景是否超过了当前设计的简单性?
非常感谢评论。
【问题讨论】:
-
Thread.Sleep(0); -> Thread.Sleep(10);
-
有一个
Interlocked.Increment()和Interlocked.Decrement():) -
@Eugene 我将您的评论解释为 Thread.Sleep(0) 也可能是 Thread.Sleep(10) 因为它会招致至少 10 毫秒的惩罚
-
@Carlos P,永远不要使用 Thread.Sleep(0),因为它没用——它会极大地利用你的 CPU。设置一些实际延迟的最佳方法 - 它会减少 CPU 消耗,尤其是在您的 do/while 情况下。
-
@Eugene, @TimWi: bluebytesoftware.com/blog/…
标签: c# .net multithreading concurrency