Воспроизвести звук, дождаться его окончания, а затем что-нибудь сделать?

Я пишу приложение Windows Forms, которое должно воспроизводить три звуковых файла и в конце каждого звукового файла изменять источник изображения.

Я могу заставить его воспроизводить звуки с помощью System.Media.SoundPlayer. Однако, похоже, он воспроизводит звук в другом потоке, продолжая.

В конечном итоге воспроизводится только последний звук и изменяются все изображения.

Я пробовал Thread.Sleep, но он спит весь графический интерфейс, и после периода сна все происходит сразу, и последний звук, который он воспроизводил.

ОБНОВИТЬ

Я думал, что PlaySynch работает, но, похоже, мой графический интерфейс замораживается, что далеко не идеально. Что еще я могу сделать?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
13 145
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Вы пробовали SoundPlayer.PlaySync Метод? Из справки:

The PlaySync method uses the current thread to play a .wav file, preventing the thread from handling other messages until the load is complete.

Да, я только что нашел это, единственная проблема в том, что графический интерфейс не нарисован ... Буду продолжать работать над этим.

Omar Kooheji 29.09.2008 17:46

Вместо использования метода Play используйте метод PlaySync.

Что вы, вероятно, захотите сделать, так это сделать асинхронный звук, но затем отключить свой пользовательский интерфейс таким образом, чтобы он не реагировал на ответ пользователя. Затем, как только звук будет воспроизведен, вы снова активируете свой пользовательский интерфейс. Это позволит вам по-прежнему рисовать пользовательский интерфейс как обычно.

Я понял, как это сделать. Я использовал PlaySynch, но я играл в отдельном потоке для кода, который рисует пользовательский интерфейс. Этот же поток также обновляет пользовательский интерфейс после воспроизведения каждого файла.

Используйте этот код:

[DllImport("WinMM.dll")]
public static extern bool  PlaySound(byte[]wfname, int fuSound);

//  flag values for SoundFlags argument on PlaySound
public static int SND_SYNC        = 0x0000;      // Play synchronously (default).
public static int SND_ASYNC       = 0x0001;      // Play asynchronously.
public static int SND_NODEFAULT   = 0x0002;      // Silence (!default) if sound not found.
public static int SND_MEMORY      = 0x0004;      // PszSound points to a memory file.
public static int SND_LOOP        = 0x0008;      // Loop the sound until next sndPlaySound.
public static int SND_NOSTOP      = 0x0010;      // Don't stop any currently playing sound.
public static int SND_NOWAIT      = 0x00002000;  // Don't wait if the driver is busy.
public static int SND_ALIAS       = 0x00010000;  // Name is a registry alias.
public static int SND_ALIAS_ID    = 0x00110000;  // Alias is a predefined ID.
public static int SND_FILENAME    = 0x00020000;  // Name is file name.
public static int SND_RESOURCE    = 0x00040004;  // Name is resource name or atom.
public static int SND_PURGE       = 0x0040;      // Purge non-static events for task.
public static int SND_APPLICATION = 0x0080;      // Look for application-specific association.
private Thread t; // used for pausing
private string bname;
private int soundFlags;

//-----------------------------------------------------------------
public void Play(string wfname, int SoundFlags)
{
    byte[] bname = new Byte[256];    //Max path length
    bname = System.Text.Encoding.ASCII.GetBytes(wfname);
            this.bname = bname;
            this.soundFlags = SoundFlags;
            t = new Thread(play);
            t.Start();
}
//-----------------------------------------------------------------

private void play()
{
    PlaySound(bname, soundFlags)
}

public void StopPlay()
{
    t.Stop();
}

public void Pause()
{
    t.Suspend(); // Yeah, I know it's obsolete, but it works.
}

public void Resume()
{
    t.Resume(); // Yeah, I know it's obsolete, but it works.
}

Я считаю, что это серьезный перебор.

Anonymous Pi 15.03.2014 00:09

Другие вопросы по теме