牛刀小試:使用Reactive Extensions(Rx),一行代碼實現多線程任務執行規定時間后自動停止


內容摘要:

這是之前有一個朋友項目中實際遇到的問題:在一個窗口中,希望點擊某個按鈕后(或者同類操作),播放一個警告的聲音,很顯然,這個音頻播放是用異步來實現。但又希望播放一段時間后,自動地停止播放。

這個問題要說難也不是很難,我們無非是要想辦法做一個計時,到達規定時候(例如5秒)后,強制地將線程結束掉。問題出在如何寫較為理想些。

 

問題分析:

播放音頻本身不難,而且在WPF中,音頻播放默認就是異步的,根本不需要我們單獨去啟動線程。代碼大致如下

                var player = new SoundPlayer();
                player.SoundLocation = "bell.wav";
                player.PlayLooping();

 

這里的player一般會有兩個方法:Play 和PlayLooping。前者是播放一次,后者是一直播放。但他們都是異步執行的。

如果需要同步執行,則倒是需要調用PlaySync,考慮到播放音頻可能需要的時間較長,一般是不建議用同步的方式的。

而player本身有一個Stop方法,可以終止播放(同時也會將線程關閉或者歸還到線程池)。

所以,問題的關鍵就在於,如何在規定的時間后,調用player.Stop方法。

常規做法:

從最簡單粗暴的角度出發,我們可以用一個定時器,定時一定時間(例如5秒鍾),到了這個時間,就調用player.Stop方法,並且將定時器也停止掉。(所以其實這個定時器只會被觸發一次,我們用它的目的只是希望它能在5秒鍾后被喚醒起來做事情)

            var player = new SoundPlayer();
            player.SoundLocation = "bell.wav";

            var timer = new DispatcherTimer(TimeSpan.FromSeconds(5), DispatcherPriority.Normal, (source, args) =>
            {
                player.Stop();
                ((DispatcherTimer)source).Stop();

            }, this.Dispatcher);

            timer.Start();
            player.PlayLooping();

看起來怎么樣呢?問題肯定是解決了。但是有沒有更好的方法呢?

 

引入Reactive Extensions:

我聯想到之前我正好在研究Reactive Extensions(簡稱Rx),這是微軟提供的一個針對異步和事件處理的增強框架。它的官方地址在:http://msdn.microsoft.com/en-us/data/gg577609.aspx ,目前最新的版本是2.0.

Reactive Extensions提供了一種全新的視角,讓我們來處理事件,和異步任務。它首先是對異步處理和事件進行了一些包裝,然后,它的核心是,通過Obserable和Observer的機制,實現所謂響應式的編程體驗。最后,它結合Linq,提供了語法上面的極大便利。

我對Reactive Extensions的研究也還算不上透徹,逐漸會有一些更多的分享出來吧。這個問題正好遇到了,所以想到可能用Rx來做,代碼會更加易於閱讀,本質上肯定也是有一個等待的過程,但不用Timer去做了。

你可以直接在Visual Studio中導入幾個Rx的Package

image

解決方案:

我最終的解決方案如下。你覺得怎么樣?是否有更加好的做法呢?

            Observable.Start<SoundPlayer>(() =>
            {
                var player = new SoundPlayer();
                player.SoundLocation = "bell.wav";
                player.PlayLooping();

                return player;
            }).Delay(TimeSpan.FromSeconds(5)).Subscribe(player => player.Stop());
 
 
【備注】本來想要做一個視頻的,但因為近日都在外講課,嗓子要盡量保護。所以就通過文字寫出來吧
完整代碼請通過這里下載 http://files.cnblogs.com/chenxizhang/WpfApplicationSample-rx.zip
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM