牛刀小试:使用Reactive Extensions(Rx),一行代码实现多线程任务执行规定时间后自动停止
2012-09-19 17:37
906 查看
内容摘要:
这是之前有一个朋友项目中实际遇到的问题:在一个窗口中,希望点击某个按钮后(或者同类操作),播放一个警告的声音,很显然,这个音频播放是用异步来实现。但又希望播放一段时间后,自动地停止播放。这个问题要说难也不是很难,我们无非是要想办法做一个计时,到达规定时候(例如5秒)后,强制地将线程结束掉。问题出在如何写较为理想些。
问题分析:
播放音频本身不难,而且在WPF中,音频播放默认就是异步的,根本不需要我们单独去启动线程。代码大致如下varplayer=newSoundPlayer(); player.SoundLocation="bell.wav"; player.PlayLooping();
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
这里的player一般会有两个方法:Play和PlayLooping。前者是播放一次,后者是一直播放。但他们都是异步执行的。
如果需要同步执行,则倒是需要调用PlaySync,考虑到播放音频可能需要的时间较长,一般是不建议用同步的方式的。
而player本身有一个Stop方法,可以终止播放(同时也会将线程关闭或者归还到线程池)。
所以,问题的关键就在于,如何在规定的时间后,调用player.Stop方法。
常规做法:
从最简单粗暴的角度出发,我们可以用一个定时器,定时一定时间(例如5秒钟),到了这个时间,就调用player.Stop方法,并且将定时器也停止掉。(所以其实这个定时器只会被触发一次,我们用它的目的只是希望它能在5秒钟后被唤醒起来做事情)varplayer=newSoundPlayer(); player.SoundLocation="bell.wav"; vartimer=newDispatcherTimer(TimeSpan.FromSeconds(5),DispatcherPriority.Normal,(source,args)=> { player.Stop(); ((DispatcherTimer)source).Stop(); },this.Dispatcher); timer.Start(); player.PlayLooping();
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
看起来怎么样呢?问题肯定是解决了。但是有没有更好的方法呢?
引入ReactiveExtensions:
我联想到之前我正好在研究ReactiveExtensions(简称Rx),这是微软提供的一个针对异步和事件处理的增强框架。它的官方地址在:ReactiveExtensions提供了一种全新的视角,让我们来处理事件,和异步任务。它首先是对异步处理和事件进行了一些包装,然后,它的核心是,通过Obserable和Observer的机制,实现所谓响应式的编程体验。最后,它结合Linq,提供了语法上面的极大便利。
我对ReactiveExtensions的研究也还算不上透彻,逐渐会有一些更多的分享出来吧。这个问题正好遇到了,所以想到可能用Rx来做,代码会更加易于阅读,本质上肯定也是有一个等待的过程,但不用Timer去做了。
你可以直接在VisualStudio中导入几个Rx的Package
解决方案:
我最终的解决方案如下。你觉得怎么样?是否有更加好的做法呢?Observable.Start<SoundPlayer>(()=> { varplayer=newSoundPlayer(); player.SoundLocation="bell.wav"; player.PlayLooping(); returnplayer; }).Delay(TimeSpan.FromSeconds(5)).Subscribe(player=>player.Stop());
【备注】本来想要做一个视频的,但因为近日都在外讲课,嗓子要尽量保护。所以就通过文字写出来吧
完整代码请通过这里下载http://files.cnblogs.com/chenxizhang/WpfApplicationSample-rx.zip
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
相关文章推荐
- 牛刀小试:使用Reactive Extensions(Rx),一行代码实现多线程任务执行规定时间后自动停止
- 一行代码实现多线程任务执行规定时间后自动停止
- c#实现每隔规定时间自动执行程序代码
- JDK实现规定时间执行规定任务代码
- 使用任务计划功能结合shutdown命令让Win7实现定时自动执行
- 用C#用C#实现窗体在规定时间弹出,例如:10:00.弹出后关闭。并在5分钟后再次弹出。5次后停止。最好有具体代码实现窗体在规定时间弹出,例如:10:00.弹出后关闭。并在5分钟后再次弹出。5次后停止。最好有具体代码
- pyqt5 使用 QTimer, QThread, pyqtSignal 实现自动执行,多线程,自定义信号触发。
- 使用Zookeeper实现集群中选择单机器执行任务并自动切换
- java起一个定时任务,在规定的时间内自动执行
- 使用java并发工具栅栏(CyclicBarrier)实现多线程等待,同一时刻执行共同任务
- iOS开发—使用GCD实现多线程(单次或重复执行任务)
- java中实现定时任务每天规定时间执行任务一次
- 关于Java Web 使用Spring中使用Quartz(定时调用、实现固定时间执行), 触发定时器(执行某些任务)的实例
- java系统中使用调度器Quartz实现对正在执行任务的停止
- 用C#用C#实现窗体在规定时间弹出,例如:10:00.弹出后关闭。并在5分钟后再次弹出。5次后停止。最好有具体代码实现窗体在规定时间弹出,例如:10:00.弹出后关闭。并在5分钟后再次弹出。5次后停止。最好有具体代码
- Android 使用定时器在指定日期及时间执行任务
- 使用Auto Layout-代码实现自动布局
- 编写一个聊天程序:有接收数据部分,和发数据的部分, 这两部分需要同时执行,使用多线程实现,一个控制接收,一个控制发送
- [多线程]闭锁 通过闭锁CountDownLatch计算多线程下任务的执行时间
- 2018.01.30.v-for的使用、css实现自动换行,时间戳的简单使用。