如何在C#中停止线程?

时间:2018-08-01 13:19:24

标签: c# multithreading visual-studio-2017

信息:我正在Visual Studio 2017中使用C#创建游戏

如何停止音乐线程?是否有可能采用其他形式? 我用这段代码创建了在后台播放音乐的线程

MediaPlayer bg;

public void main()
{
    IntializeComponent();
    Bg_music();
}

private void Bg_music()
{
    new System.Threading.Thread(() =>
    {
        bg = new System.Windows.Media.MediaPlayer();
        bg.Open(new System.Uri(path + "Foniqz_-_Spectrum_Subdiffusion_Mix_real.wav"));
        bg.Play();
    }).Start();                        
}

当我尝试使用此代码停止线程时,它将停止当前打开的窗口,并且音乐/线程会继续播放音乐

bg.Dispatcher.Invoke(() =>
{
    bg.Close();
});

这也不起作用

bg.Dispatcher.Invoke(() =>
{
    bg.Stop();
});

2 个答案:

答案 0 :(得分:1)

假设您确实需要后台线程(因为MediaPlayer在WPF上是非阻塞的),您可能需要在C#中使用以下路径之一:

  1. 使用取消令牌和任务:

        MediaPlayer bg;
    readonly CancellationTokenSource tokenSource = new CancellationTokenSource();
    public MainWindow()
    {
        InitializeComponent();
        Bg_music();
    }
    
    private void Bg_music()
    {
    
        Task.Run(() =>
        {
            bg = new MediaPlayer();
            bg.Open(new Uri(@"D:\Songs\201145-Made_In_England__Elton_John__320.mp3"));
            bg.Play();
            bg.Play();
            while (true)
            {
                if (tokenSource.Token.IsCancellationRequested)
                {
                    bg.Stop();
                    break;
                }
            }
    
        }, tokenSource.Token);
    
    }
    
    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
           tokenSource.Cancel();
    }
    

    }

  1. 使用事件通过任务进行通信。 (停止使用线程,我们现在有任务)

答案 1 :(得分:-1)

跨线程对象访问可能很棘手。

一旦在UI线程以外的其他线程中创建MediaPlayer实例,由于该对象不属于UI线程,则在UI线程内访问该对象将抛出InvalidOperationException

    private void Bg_music()
    {
        bg = new System.Windows.Media.MediaPlayer();
        new System.Threading.Thread(() =>
        {
            bg.Dispatcher.Invoke(()=>{
                bg.Open(new System.Uri(path + "Foniqz_-_Spectrum_Subdiffusion_Mix_real.wav"));
                bg.Play();
            });

        }).Start();                        
    }

现在,当在UI线程中调用Dispatcher时,不必使用MediaPlayer来停止curl -v -o package.war -H "Authorization: Basic token..." "https://tfs.company.com/tfs/myCollectin/myProject/_packaging?feed=myFeed&package=com.company.application%3Apackage&version=1.0&protocolType=maven&_a=package#"

编辑:即使实施的方法不是最佳实践,仍然值得回答一些理论信息。