我创建了一个声音播放器,可以在任何给定时间从一组声音中播放一个特定的声音。集合中的其中一个声音需要以循环方式播放。下面是我的代码:
public class SoundService : ISoundService
{
private Dictionary<string, SoundPlayer> SoundCollections { get; set; }
private SoundPlayer _soundPlayerPlaceHolder;
private readonly CancellationTokenSource _cancellationToken = new CancellationTokenSource();
private CancellationToken _token;
public void Play(SoundType soundType)
{
_token = _cancellationToken.Token;
Task.Factory.StartNew(() => PlaySound(soundType), _token);
}
private void PlayLooping(SoundType soundType)
{
if (!SoundCollections.ContainsKey(soundType.ToString()))
{
s_Log.Error("Error retrieving sound from Sound collection. XXX.SoundService");
return;
}
_soundPlayerPlaceHolder = SoundCollections[soundType.ToString()];
if (_token.IsCancellationRequested)
{
if (_soundPlayerPlaceHolder != null)
{
_soundPlayerPlaceHolder.Stop();
_soundPlayerPlaceHolder = null;
}
return;
}
_soundPlayerPlaceHolder.PlayLooping();
}
public void StopSound()
{
_cancellationToken.Cancel();
}
public void LoadSounds()
{
var sounds = Enum.GetValues(typeof (SoundType));
SoundCollections = new Dictionary<string,SoundPlayer>();
foreach (var soundType in sounds)
{
var resourceName = GetResourceNameAttribute(soundType);
if (string.IsNullOrEmpty(resourceName))
continue;
try
{
var stream = Resources.ResourceManager.GetStream(resourceName);
var soundPlayer = new SoundPlayer(stream);
soundPlayer.LoadAsync();
SoundCollections.Add(soundType.ToString(), soundPlayer);
s_Log.Info(string.Format(@"loading sound {0}", soundType));
}
catch (Exception e)
{
s_Log.Error(e);
}
}
}
private string GetResourceNameAttribute(object enumToQuery)
{
var fi = enumToQuery.GetType().GetField(enumToQuery.ToString());
var attributes = (ResourceNameAttribute[])fi.GetCustomAttributes(
typeof(ResourceNameAttribute), false);
return attributes.Length > 0 ? attributes[0].ResourceName : enumToQuery.ToString();
}
/// <summary>
/// .
/// </summary>
/// <param name="aSoundType"></param>
private void PlaySound(SoundType aSoundType)
{
s_Log.Info("loading sound {0}", aSoundType.ToString());
if (aSoundType == SoundType.ItemNotFound)
{
PlayLooping(aSoundType);
}
else
{
if (_soundPlayerPlaceHolder == null)
SoundCollections[aSoundType.ToString()].Play();
}
}
}
我遇到的问题是在声音播放器循环播放(正在工作)并且取消令牌被取消后,我无法再循环播放相同的声音。我不确定为什么会这样,我尝试了许多其他线程选项(任务、BackgroundWorker),但我没有运气。单曲工作正常,它只是重播循环那不起作用。没有例外,日志中没有任何内容......我迷路了......想法?