簡體   English   中英

如何在C#中停止線程?

[英]How to stop thread in C#?

信息:我正在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();
});

假設您確實需要一個后台線程(由於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. 使用事件通過任務進行通信。 (停止使用線程,我們現在有任務)

跨線程對象訪問可能很棘手。

一旦在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線程中調用MediaPlayer時,不必使用Dispatcher來停止它。

編輯:即使實施的方法不是最佳實踐,仍然值得回答一些理論信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM