Я рисую визуализацию для записи данных WaveIn только для целей тестирования, чтобы увидеть, насколько правильными являются данные.Как вы можете видеть, мой механизм:
1) Некоторые потоки WaveIn (не включены) проталкивают эту форму через делегата с аудиобуфером.
2) Фоновый рабочий принимает обновленные аудиоданные,рисовать Bitmap и когда он закончится, он сообщает Progress и этот дескриптор из этого собственного потока формы просто вызывает WM_PAINT для обновления фона PictureBox новым изображением.
object localLock = new object();
Bitmap soundGraphImage;
private void soundGrapher_DoWork(object sender, DoWorkEventArgs e) {
while(are.WaitOne())
{
if (soundGrapher.CancellationPending) {
e.Cancel = true;
return;
}
if (audioData == null || audioData.Length == 0) continue;
soundGraphImage = new Bitmap(graphWidth, graphHeight); <----- this one
Graphics g = Graphics.FromImage(soundGraphImage);
lock (localLock)
{
#region Draw sound
if (audioParms.nChannels > 1) { Vfw_MessageOut("More than 1 channel"); return; }
int currentPos = 1;
int accu = 0;
int x = 1;
int maxValue = 0;
int baseY = soundGraph.Height / 2;
int bytes = audioParms.wBitsPerSample / 8;
int portion = (int)Math.Round(1.0 * audioData.Length / bytes / soundGraph.Width, MidpointRounding.ToEven);
switch (bytes)
{
case 1: maxValue = Byte.MaxValue; break;
case 2: maxValue = Int16.MaxValue; break;
case 4: maxValue = Int32.MaxValue; break;
}
int halfValue = maxValue / 2;
double coeff = multiPlyer * baseY / halfValue;
for (int i = 0; i < audioData.Length; i = i + bytes)
{
if (currentPos == portion)
{
accu = (int)(accu / portion);
g.DrawLine(Pens.White, new Point(x, baseY),
new Point(x, baseY - (int)(coeff * accu)));
currentPos = 1;
i = i - bytes;
x++;
}
else
{
currentPos++;
switch (bytes)
{
case 1: accu += audioData[i] - halfValue; break;
case 2: accu += BitConverter.ToInt16(audioData, i); break;
case 4: accu += BitConverter.ToInt32(audioData, i); break;
}
}
}
#endregion
}
g.Dispose();
soundGrapher.ReportProgress(0);
}
}
private void soundGrapher_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
}
private void soundGrapher_ProgressChanged(object sender, ProgressChangedEventArgs e) {
soundGraph.Invalidate();
}
Проблема в Bitmap .. этот код вызывает утечку памяти,Пожалуйста, помогите мне избежать этой проблемы.
ОБНОВЛЕНИЕ
Да, решение легко, просто избавиться от него .. Я бы получил, конечно, сам, ноУ меня все еще есть более серьезная проблема, и это растровое изображение было только на вершине моего стека, когда оно дошло до стадии, называемой stackoverflow.Но в любом случае это вина ГК .. он должен контролировать такие вещи.Обратный вызов высовывается один раз в секунду. Я никогда не вызывал Dispose для каждого растрового изображения в моих предыдущих проектах.