【问题标题】:Traversing List C#遍历列表 C#
【发布时间】:2016-11-30 09:34:06
【问题描述】:

我正在玩一些 C#,我正在编写一个钢琴应用程序。

每当用户单击钢琴音符时,我都会将声音的位置 (.wav) 存储到一个列表中...以下是 button1_MouseDown 方法中的一些代码。

if (e.Button == MouseButtons.Left)
   {
       SoundPlayer sp = new SoundPlayer();
       string musName = Convert.ToString(mk.pitch);
       string loc = @"D:\OneDrive\Year 2 Semester 1\OOP\Notes-Sound files\Notes-Sound files\mapped\" + musName + ".wav";
       sp.SoundLocation = loc;
       sp.Play();
       music.Add(loc);
    }

现在,我想遍历循环以一次性播放所有点击的键。我这样做如下(当用户点击播放按钮时)

int k = 0;
for (k = 1; k < music.Count; k++)
{
   SoundPlayer sp = new SoundPlayer();
   sp.SoundLocation = music[k];
   sp.Play();
 }

问题是,每当单击播放按钮时,只会播放最后按下的音符。但是,当我调试时,不知何故,所有音符都会播放。有什么想法吗?

【问题讨论】:

  • 你好,我认为你必须等到每个音符都弹完后才能弹下一个
  • 我还假设你不需要在每次迭代中初始化一个新播放器,而是在循环之外。

标签: c# list for-loop soundplayer piano


【解决方案1】:

根据MSDN,这是Play方法的描述:

使用新线程播放 .wav 文件,如果 .wav 文件尚未加载,则首先加载它。

因此,每当您调用Play 时,它都会异步运行,并且您的循环会在当前文件完成之前继续执行播放下一个 wav 文件。调试时,您可能一直在等待,然后再继续循环。

请尝试使用PlaySync 同步播放声音

PS。此外,您可能需要考虑在列表中使用 SoundPlayer 的实例而不是文件名,以避免每次播放 wav 文件时都创建新实例:

List<SoundPlayer> music = new List<SoundPlayer>();
//...

//In your first loop, you would add the SoundPlayer object
music.Add(sp);

//.. 
//Then when you're playing back:
for (int k = 0; k < music.Count; k++)
{
   music[k].PlaySync();
}

请注意,for 循环中的索引也应该从 0 开始

【讨论】:

  • @KMoussa 我应该在哪里放置'var music = new List();'
  • @AxelAzzopardi 代替您当前声明的 music 列表/数组 strings
  • 不会像本例那样在 不同的 SoundPlayers 上调用 PlaySync,导致它实际异步运行?音乐[1] 如何知道音乐[0] 何时播放完毕?只运行一个 MusicPlayer,然后在循环中更改 SoundLocation 并同步播放不是更好吗?
  • @KMoussa 发生错误,因为 var 可能只出现在局部变量声明中。我有两种方法。如果我把它放在一种方法中,另一种方法找不到它。
  • @AxelAzzopardi 抱歉我的错误,您不能将var 用于班级成员,请尝试将List&lt;SoundPlayer&gt; music = new List&lt;SoundPlayer&gt;(); 作为班级中的字段
【解决方案2】:

您可能需要使用LoadAsync 播放声音Asynchronously,如下所示:How to: Load a Sound Asynchronously within a Windows Form

【讨论】:

    【解决方案3】:

    您的主要问题是所有音符都在播放,但随后的音符实际上在第一个音符完成之前开始播放。因此,您只听到最后一个。

    使用PlaySync,它会同步播放声音,如果您出于某种原因必须遍历List&lt;&gt; 并说,请在播放前检查每个项目(好吧,至少如果您将 SoundPlayer 派生到另一个类,以便它实际上有要检查的东西),您可以对 PlaySync 调用使用检查。

    SoundPlayer sp = new SoundPlayer();
    
    foreach(var note in music)
    {
        sp.SoundLocation = note;
        bool everythingIsFine = false;
    
        // Logic for everythingIsFine;
    
        if(everythingIsFine){
            sp.PlaySync(); 
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-02-11
      • 1970-01-01
      • 1970-01-01
      • 2017-12-10
      • 1970-01-01
      • 2010-12-18
      • 2022-01-07
      相关资源
      最近更新 更多