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

Posted

技术标签:

【中文标题】与意外的交叉线程和停止作斗争【英文标题】:Struggling with Unexpected Cross-Thread and Halt 【发布时间】:2015-07-05 00:39:40 【问题描述】:

我正在使用 NAudio 库为我自己的音频播放器应用程序创建播放列表功能,并完成了源代码。但是,在调试时,发生了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;
    

...而且,这是我声明 CheckForIllegalCrossThreadCalls = 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 将阻止它检测错误,但它不会阻止错误导致导致程序停止的问题。你可能想把它拿出来,这样你就可以看到实际发生了什么。 【参考方案1】:

删除构造函数中的 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;
        );
    

【讨论】:

谢谢,但程序在 _waveOutDevice.Init(_audioFileReader); 处暂停

以上是关于与意外的交叉线程和停止作斗争的主要内容,如果未能解决你的问题,请参考以下文章

直连网线与交叉网线

直通线交叉线反转线怎么连接

visio 交叉线 不出现拱形怎么办?

如何同时使用交叉验证和提前停止?

网线的直连线与交叉线之间的区别

在 LIBSVM 中的 SVM 中进行交叉验证时停止打印准确性 [关闭]