Код в вопросеПочему этот код ThreadPool.QueueUserWorkItem не сбивает мой тест?
public void StartPlaying()
{
ThreadPool.QueueUserWorkItem(ignoredState =>
{
while (_playlist.Count > 0)
{
var audioFile = _playlist.Dequeue();
if (StartedPlaying != null)
StartedPlaying(this, new TypedAudioFileEventArgs(audioFile));
audioFile.SoundPlayer.PlaySync();
audioFile.SoundPlayer.Dispose();
if (StoppedPlaying != null)
StoppedPlaying(this, new TypedAudioFileEventArgs(audioFile));
}
});
}
и мой тест:
[TestMethod()]
public void StartPlayIsCalledTwice_OnlyRunningOnce()
{
int timeBetweenPlays = 0;
var target = new TypedAudioFilePlayer(timeBetweenPlays);
target.AddFile(TypedAudioFileCreator.CreateWord(1, "bl"));
target.StartedPlaying += StartedPlaying_Once;
target.StartPlaying();
target.StartPlaying();
}
private bool _once = false;
private void StartedPlaying_Once(object sender, TypedAudioFileEventArgs e)
{
if (!_once)
_once = true;
else
Assert.Fail("Should not be called more than once!");
}
Я считаю, что мой блок тест должен потерпеть неудачу, судя по описанию MSDN из ThreadPool.QueueUserWorkItem
:
Очереди метод для выполнение. Метод выполняется, когда поток пула потоков становится доступным.
Размер потока ThreadPool по умолчанию равен 512, поэтому для обработки вызова StartPlaying должны быть доступны сразу два потока. Я считаю, что мой код не сработает, поскольку я не предоставил никаких гарантий из условий гонки, в которых оба потока могут получить доступ к одному и тому же ресурсу.
Что здесь происходит?
пытаются объявить _once летучим ... –
@Mitch: Пробовали, тест по-прежнему проходит. Мне нравится, как то, что должно быть технически хорошо (тест прохождения), оказывается источником страха и путаницы (ПОЧЕМУ вы проходите !?). Хех, программные методологии - это весело. – IAE
Даже если в этом коде не было условий гонки, Assert будет поднят в другом потоке в тот, который выполняет тест. – porges