2

だから私はいくつかのNAudioのものを初期化するパラメータ化されたスレッドの開始を持っています...しかし、私は別のスレッドがNAudioスレッドに開始するように伝える必要があります。試してみると、クラッシュします。安全なクロススレッド通信を実装するにはどうすればよいですか?

スレッドは次のとおりです (このクラスは、メイン スレッドのオーディオ オブジェクトになります)。

class Audio
{
    public IWavePlayer OutDevice;
    public WaveStream OutStream;

    public Thread thread;

    public Audio(string file)
    {
        this.thread = new Thread(new ParameterizedThreadStart(InitAudio)); thread.Start(file);
    }

    private void InitAudio(object data) {

        this.OutDevice = new WaveOut();
        this.OutStream = new WaveChannel32(new Mp3FileReader(data.ToString()));
        this.OutDevice.Init(OutStream);
    }
}

メインスレッドで audio.OutDevice.Play(); を呼び出せるようにする必要があります。しかし、クロススレッドでクラッシュするため、できません。どうすればいいですか?

4

2 に答える 2

0

バックグラウンド スレッドでオーディオ バッファーをいっぱいにする場合は、WaveOutEvent クラスを使用することをお勧めします。これにより、パイプラインを介してオーディオをプルするための独自のバックグラウンド スレッドが作成されます。その後、メイン スレッドから Play と Stop を呼び出すことができます。この状況で注意する必要がある主なスレッドの問題は、再生中のファイル内で再配置を実装する必要がある場合です。これは、再配置が GUI スレッドで発生し、別のスレッドで読み取りが進行中の可能性があるためです。

WinForms/WPF アプリの場合、最も信頼性の高いメカニズムは、WaveOut の Windows メッセージ コールバックを使用することです (GUI スレッドで WaveOut を作成すると、デフォルトでこれが取得されます)。これにより、再配置するスレッドについて心配する必要がなくなります。また、すべてに GUI スレッドを使用することで、Windows Media API、MediaFoundation、DirectX Media Object リサンプラーなどの COM ベースの API を使用する場合に発生する可能性のある MTA と STA のスレッドの問題を回避します。

于 2013-02-28T11:59:22.723 に答える
0

オーディオの再生はハードウェア リソースを使用しており、通常、それらは作成されたのと同じスレッドでアクセスする必要があります。あなたのコードでは、スレッドに継続的にアクセスする余地がありませんでした。所有しているスレッドがまもなく範囲外になるため、そのコードの音が聞こえたことに驚いています。何かが起こったのは、これらの変数がクラスに関連付けられているからです。個人的には、再生はノンブロッキングである、またはノンブロッキングである可能性があると考えているため、このシナリオでは別のスレッドは必要ないと思います。それにもかかわらず、次のようなもの (疑似コード) で計画に従うことができます。

public bool ShouldPlay;
private void InitAudio(object data) {

        var OutDevice = new WaveOut();
        var OutStream = new WaveChannel32(new Mp3FileReader(data.ToString()));
        var OutDevice.Init(OutStream);

        while(!_exitEvent.WaitOne(50ms)){
                 if(ShouldPlay && !OutDevice.IsPlaying)
                        OutDevice.Play();
                 else if(!ShouldPlay && OutDevice.IsPlaying)
                        OutDevice.Stop();
            }
          OutDevice.Stop();
          OutDevice.Dispose();
          OutStream.Dispose();
    }
于 2013-02-28T03:30:36.313 に答える