我有一种方法可以迭代一系列音乐笔记并一个接一个地播放它们。我创建了一个进度条,它将显示foreach循环的状态。 问题是进度条没有达到100%但大约达到85%。我还注意到进度条大致进展,我认为这可能是因为步骤很大。关于如何优化此进度条的任何想法,pb是我的进度条实例,谢谢
public void PlayAll()
{
pb.Maximum = Convert.ToInt32(CountTotalDuration()); //Total lenght of the full song.
pb.Step = Convert.ToInt32(CountTotalDuration()) / Convert.ToInt32(ListSize()); //Total lenght of each note making up the song.
foreach (MusicNote m in list)
{
m.sp.Stop();
m.sp.Play();
Thread.Sleep(m.NoteDuration*100);
pb.PerformStep();
}
}
答案 0 :(得分:3)
您的问题来自于您的步骤中的舍入错误。让我们看一个简单的例子,假设你有CountTotalDuration()
100
和ListSize()
7
因为您有两个整数/
执行整数除法并抛弃任何余数,因此100 / 7
等于14
(而不是14.285714
且重复285714
。这使得您的步长为14,因此在完成7个步骤后,您达到的总值为98
,您将在工具栏上看到98%。
由于CountTotalDuration()
似乎是NoteDuration
的总和,解决这个问题的方法是每步不使用相等的步长。相反,只需将最大值设置为总持续时间,并通过手提箱持续时间增加条形。这将使条形按照音符长度与乐曲中的位置成比例跳跃。
public void PlayAll()
{
pb.Maximum = Convert.ToInt32(CountTotalDuration()); //Total lenght of the full song.
int currentCount = 0; //Initialize our counter to 0.
foreach (MusicNote m in list)
{
m.sp.Stop();
m.sp.Play();
Thread.Sleep(m.NoteDuration*100);
//Increment the counter proportional to the length of the note.
currentCount += m.NoteDuration;
//Set the progress bar using our calculated position.
pb.Value = currentCount;
}
}
当长音符播放时,你仍然会有很大的跳跃,解决这个问题的唯一方法就是不使用Thread.Sleep(m.NoteDuration*100);
而是使用多个较短的暂停并在这些暂停之间更新条形码。另外Thread.Sleep
可能不是暂停循环的最佳方法,但我不知道最好的替代方法是什么,这取决于你没有与我们分享的很多细节。
您可能也会对旧方法有类似的行为,并且对于每个播放的音符都会使音符跳过1,并使条形的最大值等于您将播放的音符数。
public void PlayAll()
{
pb.Maximum = list.Length; //Or equivalent, perhaps ListSize()?
pb.Step = 1;
foreach (MusicNote m in list)
{
m.sp.Stop();
m.sp.Play();
Thread.Sleep(m.NoteDuration*100);
pb.PerformStep();
}
}
这样可以为每个音符提供更均匀的跳跃,但如果这首歌只有几个音符,那么即使跳跃也可能非常大。
答案 1 :(得分:1)
听起来很奇怪,我没有发现问题,但我建议你可以这样试试:
public void PlayAll()
{
pb.Maximum = Convert.ToInt32(ListSize()); //Total lenght of the full song.
pb.Step = 1;
int i = 1;
foreach (MusicNote m in list)
{
m.sp.Stop();
m.sp.Play();
Thread.Sleep(m.NoteDuration * 100);
pb.Value = i++;
}
}
更进一步,也许你应该使用多线程来改善用户体验,因为Thread.Sleep()使表单像死的一样。