2

我对编程非常陌生,仍然需要掌握很多基础知识。但我已经设法在各处的帮助下制作了一个完整的程序。但是,我认为我的资源存在内存泄漏,我还是新手,几乎可以肯定这是一种笨拙的方法......

我目前在我的应用程序中有背景音乐,它使用存储在 My.Resources 中的 .wav 文件。我已经实施了多种措施来成功启用、禁用和静音音频,但是当我引入多个音轨时遇到了障碍。这个想法是在我的程序的“设置”区域中为最终用户提供 4 首背景歌曲(存储为 4 个 .wav 资源)之间的选项。当我构建和测试解决方案时,它运行良好,一切都符合预期。然后,当我在设置区域中将音频更改为不同的轨道时,它也可以工作。当我多次更改歌曲时会发生障碍,我收到 OutOfMemory 错误。

我想我明白发生了什么;每次用户选择资源时,都会将资源添加到内存中,但是如果选择了 -say-song2,我不知道如何从内存中删除 -say-song1。这是我处理音频选择和播放的代码。

(该程序使用称为“%chkbox”的单选按钮,并要求用户在运行此代码之前点击“savebtn”。)使用 Visual Basics 2012 .net 4.5

    'Save and start songs.

    If DjErhain_Mistychkbox.Checked = True Then
        My.Settings.AudioDJErhain_UWBeats_Maniac = 0
        My.Settings.Save()
        My.Settings.AudioDjErhain_Misty = 1
        My.Settings.Save()
        My.Settings.AudioMachinimaSound_Exigence = 0
        My.Settings.Save()
        My.Settings.AudioSimplex_Memories_master = 0
        My.Settings.Save()

        My.Computer.Audio.Play(My.Resources.DjErhain_Misty, AudioPlayMode.BackgroundLoop)


    ElseIf DJErhain_UWBeats_Maniacckbox.Checked = True Then
        My.Settings.AudioDjErhain_Misty = 0
        My.Settings.Save()
        My.Settings.AudioDJErhain_UWBeats_Maniac = 1
        My.Settings.Save()
        My.Settings.AudioMachinimaSound_Exigence = 0
        My.Settings.Save()
        My.Settings.AudioSimplex_Memories_master = 0
        My.Settings.Save()

        My.Computer.Audio.Play(My.Resources.DJErhain_UWBeats_Maniac, AudioPlayMode.BackgroundLoop)


    ElseIf MachinimaSound_Exigencechckbox.Checked = True Then
        My.Settings.AudioMachinimaSound_Exigence = 1
        My.Settings.Save()
        My.Settings.AudioDJErhain_UWBeats_Maniac = 0
        My.Settings.Save()
        My.Settings.AudioDjErhain_Misty = 0
        My.Settings.Save()
        My.Settings.AudioSimplex_Memories_master = 0
        My.Settings.Save()

        My.Computer.Audio.Play(My.Resources.MachinimaSound_Exigence, AudioPlayMode.BackgroundLoop)


    ElseIf Simplex_Memories_masterchckbox.Checked = True Then
        My.Settings.AudioSimplex_Memories_master = 1
        My.Settings.Save()
        My.Settings.AudioDJErhain_UWBeats_Maniac = 0
        My.Settings.Save()
        My.Settings.AudioDjErhain_Misty = 0
        My.Settings.Save()
        My.Settings.AudioMachinimaSound_Exigence = 0
        My.Settings.Save()

        My.Computer.Audio.Play(My.Resources.Simplex_Memories_master, AudioPlayMode.BackgroundLoop)

    Else
    End If
4

1 回答 1

1

是的,这很可能会出错,.wav 格式不是很紧凑。当您将其放入资源中时,使用该资源将创建一个 UnmanagedMemoryStream。当您不再使用它时应该将其丢弃,垃圾收集器不会经常运行以使您摆脱麻烦。

在您的项目中添加一个新模块并粘贴以下代码:

Imports System.IO

Module PlayerUtilities

    Private CurrentStream As WeakReference(Of Stream)

    Public Sub PlayResource(wave As Stream)
        My.Computer.Audio.Play(wave, AudioPlayMode.BackgroundLoop)
        Dim oldwave As Stream = Nothing
        If CurrentStream IsNot Nothing AndAlso CurrentStream.TryGetTarget(oldwave) Then
            oldwave.Dispose()
        End If
        CurrentStream = New WeakReference(Of Stream)(wave)
    End Sub

End Module

并将您对 My.Computer.Audio.Play() 的调用替换为 PlayResource()。在此方法中对上一个音频流的 Dispose() 调用将使您免于麻烦。

于 2013-11-11T20:48:04.323 回答