简体   繁体   中英

What is it in SoundPlayer.Play implementation that doesn't allow playing more than 1 sound async?

I'm trying to understand what is it in the implementation of SoundPlayer.Play that doesn't allow playing more than 1 sound async (eg, as explained here or here ). I looked into its source code , but I couldn't figured it out.

For convenience, here's the code of both SoundPlayer.Play and SoundPlayer.LoadAndPlay , which is the method called by SoundPlayer.Play :

public void Play() {
            LoadAndPlay(NativeMethods.SND_ASYNC);
        }    

private void LoadAndPlay(int flags) {
            // 
            if (String.IsNullOrEmpty(soundLocation) && stream == null) {
                SystemSounds.Beep.Play();
                return;
            }

            if (uri != null && uri.IsFile) {
                // VSW 580992: With more than one thread, someone could call SoundPlayer::set_Location
                // between the time LoadAndPlay demands FileIO and the time it calls PlaySound under elevation.
                // 
                // Another scenario is someone calling SoundPlayer::set_Location between the time
                // LoadAndPlay validates the sound file and the time it calls PlaySound.
                // The SoundPlayer will end up playing an un-validated sound file.
                // The solution is to store the uri.LocalPath on a local variable
                string localPath = uri.LocalPath;

                // request permission to read the file:
                // pass the full path to the FileIOPermission
                FileIOPermission perm = new FileIOPermission(FileIOPermissionAccess.Read, localPath);
                perm.Demand();

                // play the path
                isLoadCompleted = true;
                System.Media.SoundPlayer.IntSecurity.SafeSubWindows.Demand();

                System.ComponentModel.IntSecurity.UnmanagedCode.Assert();
                // ValidateSoundFile calls into the MMIO API so we need UnmanagedCode permissions to do that.
                // And of course we need UnmanagedCode permissions to all Win32::PlaySound method.
                try {
                    // don't use uri.AbsolutePath because that gives problems when there are whitespaces in file names
                    ValidateSoundFile(localPath);
                    UnsafeNativeMethods.PlaySound(localPath, IntPtr.Zero, NativeMethods.SND_NODEFAULT | flags);
                } finally {
                    System.Security.CodeAccessPermission.RevertAssert();
                }
            } else {
                LoadSync();
                ValidateSoundData(streamData);
                System.Media.SoundPlayer.IntSecurity.SafeSubWindows.Demand();

                System.ComponentModel.IntSecurity.UnmanagedCode.Assert();
                try {
                    UnsafeNativeMethods.PlaySound(streamData, IntPtr.Zero, NativeMethods.SND_MEMORY | NativeMethods.SND_NODEFAULT | flags);
                } finally {
                    System.Security.CodeAccessPermission.RevertAssert();
                }
            }
        }

UnsafeNativeMethods.PlaySound(winmm.dll)仅允许在每个过程的特定时间播放单个声音。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM