与意外的交叉线程和停顿作斗争

本文关键字:斗争 线程 意外 | 更新日期: 2023-09-27 18:01:08

我用NAudio Library为自己的音频播放器应用程序创建了播放列表函数,并完成了源代码。然而,在调试时,出现了InvalidOperationException,并表示跨线程发生了异常。

因此,我在表单的构造函数上声明了CheckForIllegalCrossThreadCalls=false。异常没有发生,但程序在特定行停止。

我没有将我的应用程序规划为多线程应用程序,所以没有使用或声明任何多线程组件。但是发生了跨线程异常,所以我现在很尴尬。

这是frmMain:的声明和构造函数

        AudioFileReader _audioFileReader;
        IWavePlayer _waveOutDevice = new WaveOut();
        static int nowIndex = 0;
        static bool _paused = false;
        static bool _manual_stop = false;
    public frmMain()
    {
        InitializeComponent();
        this.listMusic.DragOver += new DragEventHandler(this.FileDragOver);
        this.listMusic.DragDrop += new DragEventHandler(this.FileDragDrop);
        this.listMusic.DoubleClick += new EventHandler(this.listDoubleClick);
        _waveOutDevice.PlaybackStopped += new EventHandler<StoppedEventArgs>(this.PlaybackStopped);
    }

这是跨线程异常发生的地方。

    private void playMusic(int index)
    {
        if(_waveOutDevice.PlaybackState != PlaybackState.Stopped)
            stopMusic();
            _audioFileReader = new AudioFileReader(listMusic.Items[index].SubItems[0].Text); // Exception Occured
            getProperties(listMusic.Items[index].Text);
        _waveOutDevice.Init(_audioFileReader);
        _waveOutDevice.Play();
        btnPlayCtrl.Text = "II";
        nowIndex = index;
        _manual_stop = false;
    }

这里是我声明CheckForIllegalCrossThreadWalls=false时的停止点

        _waveOutDevice.Init(_audioFileReader); //from foregone source code.

它只是使应用程序停止,然而,它没有发生任何异常并暂停调试。当我暂停调试以分析它时,但调试器指向此处。

    [STAThread]
    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        if (args.Length > 0)
            Application.Run(new frmMain(args[1]));
        else
            Application.Run(new frmMain());
    } // Debugger Points Here

与意外的交叉线程和停顿作斗争

删除构造函数中的CheckForIllegalCrossThreadCalls = false;行。。。

然后尝试将执行移回主UI线程,如下所示:

    private void playMusic(int index)
    {
        this.Invoke((MethodInvoker)delegate
        {
            if (_waveOutDevice.PlaybackState != PlaybackState.Stopped)
                stopMusic();
            _audioFileReader = new AudioFileReader(listMusic.Items[index].SubItems[0].Text); 
            _waveOutDevice.Init(_audioFileReader);
            _waveOutDevice.Play();
            btnPlayCtrl.Text = "II";
            nowIndex = index;
            _manual_stop = false;
        });
    }