解决DoubanFM第三方客户端UI线程与工作线程交互问题
最新文章:Virson's Blog
首先要感谢yk000123的慷慨开源,开源地址见:http://doubanfm.codeplex.com/
最近正好在学习WPF,然后在Codeplex上找到了用WPF写的DoubanFM的客户端,抱着练练手的心态,着手研究代码,研究了一段时间后,准备自己加一个新功能(新功能是关于下载的,但是由于豆瓣官方版权的原因,抱歉没法为博友们提供下载,敬请谅解),于是就有了如下的问题:
在使用ThreadPool.QueueUserWorkItem()方法开始后台下载歌曲的时候,无法禁用UI界面上的下载按钮。
遇到问题和广大码农想法一样,先搜索试试看(可怜的Google):
然后找到了两篇文章,引用一下:博客园-大传神 和 CSDN-yikai2009,在此感谢两位博主的倾情付出!
问题描述:由于其他线程拥有此对象,因此调用线程无法对其进行访问 (The calling thread cannot access this object because a different thread owns it)
分析:在 WPF 中,只有创建 DispatcherObject 的线程才能访问该对象。 例如,一个从主 UI 线程派生的后台线程不能更新在该 UI 线程上创建的 Button 的内容。 为了使该后台线程能够访问 Button 的 IsEnable属性,该后台线程必须将此工作委托给与该 UI 线程关联的 Dispatcher。 使用 Invoke 或 BeginInvoke 来完成此操作。 Invoke 是同步操作,而 BeginInvoke 是异步操作。 该操作将按指定的 DispatcherPriority 添加到 Dispatcher 的事件队列中。
Invoke 是同步操作;因此,直到回调返回之后才会将控制权返回给调用对象
最终实现代码:
/// <summary>
/// 使用异步和断点续传的方式下载歌曲
/// </summary>
private void StartDownloadSongs()
{
//DownloadSearch.Search(_player.CurrentSong.Title, _player.CurrentSong.Artist, _player.CurrentSong.Album);
//BassEngine.Instance.OpenUrlAsync(_player.CurrentSong.FileUrl);
string currentSongFileUrl = _player.CurrentSong.FileUrl;
string downSavePath = DownSaveSetting.DownSavePath;
int currentSongTypePoint = currentSongFileUrl.LastIndexOf('.');
string currentSongType = currentSongFileUrl.Substring(currentSongTypePoint, currentSongFileUrl.Length - currentSongTypePoint); string strFileName = string.Empty; //包含路径的歌曲名
string currentSongTitle = _player.CurrentSong.Title.Replace("/", "&"); //当前播放歌曲的歌曲名
string currentSongArtist = _player.CurrentSong.Artist.Replace("/" , "&"); //当前播放歌曲的作者
string currentSongAlbum = _player.CurrentSong.Album.Replace("/", "&"); //当前播放歌曲的专辑 if (DownSaveSetting.IsCreateFolderByArtist)
{
string savePathWithArtist = Path.Combine(downSavePath, currentSongArtist);
if (!Directory.Exists(savePathWithArtist))
Directory.CreateDirectory(savePathWithArtist);
strFileName = savePathWithArtist + "\\" + currentSongArtist + " - " + currentSongTitle + currentSongType;
}
else
{
if (!Directory.Exists(downSavePath))
Directory.CreateDirectory(downSavePath);
strFileName = downSavePath + "\\" + currentSongArtist + " - " + currentSongTitle + currentSongType;
} if (Download.IsExistFile(strFileName))
{
MessageBoxResult result = MessageBox.Show(this,
DoubanFM.Resources.Resources.DownFileIsExistHint,
string.Empty,
MessageBoxButton.OKCancel,
MessageBoxImage.Information);
if (result == MessageBoxResult.OK)
{
//开始文件下载线程
Download.DeleteFile(strFileName);
StartDownloadSongsThread(strFileName, currentSongFileUrl);
}
}
else
{
StartDownloadSongsThread(strFileName, currentSongFileUrl);
}
} private void StartDownloadSongsThread(string strFileName, string strUrl)
{
//开始文件下载线程
ThreadPool.QueueUserWorkItem(new WaitCallback(o =>
{
this.BtnDownload.Dispatcher.BeginInvoke(new Action(delegate() { BtnDownload.IsEnabled = false; }));
if (Download.DownloadFile(strFileName, strUrl))
this.BtnDownload.Dispatcher.BeginInvoke(new Action(delegate() { BtnDownload.IsEnabled = true; }));
}));
}
解决DoubanFM第三方客户端UI线程与工作线程交互问题的更多相关文章
- Service的线程、工作线程、权限及系统Service
Service组件和其他组件一样,都是运行于应用的主线程当中,它们都运行于同一个单一的线程中. 可以把Service简单的理解成一个没有界面显示的Activity(这个比喻其实并不准确,因为Servi ...
- android中工作线程安全
当应用程序启动,创建了一个叫“main”的线程,用于管理UI相关,又叫UI线程.其他线程叫工作线程(Work Thread). Single Thread Model 一个组件的创建并不会新建一个线程 ...
- TSQLDBServerHttpApi使用工作线程池
TSQLDBServerHttpApi使用工作线程池 TSQLDBServerHttpApi创建时,默认是使用单线程模式,且只使用一个数据库连接,服务端要应对众多的客户端只靠一个工作线程(主线程)和一 ...
- JAVA之工作线程数究竟要设置多少
一.需求缘起 Web-Server通常有个配置,最大工作线程数,后端服务一般也有个配置,工作线程池的线程数量,这个线程数的配置不同的业务架构师有不同的经验值,有些业务设置为CPU核数的2倍,有些业务设 ...
- ZooKeeper:第三方客户端 ZKClient
ZKClient ZKClient的设计 ZKClient组件说明 重要的处理流程说明 启动ZKClient 为节点注册Watcher ZooKeeper的变更操作 客户端处理变更 序列化处理 ZKC ...
- Android的UI设计与后台线程交互
本文将讨论Android应用程序的线程模型以及如何使用线程来处理耗时较长的操作,而不是在主线程中执行,保证用户界面(UI)的流畅运行.本文还将阐述一些用户界面(UI)中与线程交互的API.UI用户界面 ...
- C# 多线程详解 Part.01(UI 线程、子线程)
基本概念 什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.一个进程至少有一个主线程. 什么是线程? 线程是程序中的一 ...
- 为什么说android UI操作不是线程安全的
转载于:http://blog.csdn.net/lvxiangan/article/details/17218409#t2 UI线程及Android的单线程模型原则 使用Worker线程 Commu ...
- 转载:IIS 之 连接数、并发连接数、最大并发工作线程数、队列长度、最大工作进程数
一.IIS连接数 一般购买过虚拟主机的朋友都熟悉购买时,会限制IIS连接数,顾名思义即为IIS服务器可以同时容纳客户请求的最高连接数,准确的说应该叫“IIS限制连接数”. 客户请求的连接内容包括: [ ...
随机推荐
- [Leet Code]Path Sum II
此题如果 #1 和 #4 判断分支交换,大集合就会超时(因为每次对于非叶子节点都要判断是不是叶子节点).可见,有时候if else判断语句也会对于运行时间有较大的影响. import java.uti ...
- IOS开发之UIScrollVIew运用
UIScrollView可以实现在一个界面看到所有内容,同时也不需要担心所显示的内容超出屏幕的大小,当超出之后可以翻阅至下一页浏览. #pragma mark - UIScrollViewDelega ...
- vivado自定IP例化的问题,怎么生成VHDL的例化
在tools 下面选中project settings.然后选targat language为VHDL .这样就会生成一个以VHDL语言为模板的ip. 转载:https://zhidao.baidu. ...
- [na]交换机接口文档
文档中有一些数据包等附件,pdf不能看,去这里.http://note.youdao.com/share/?id=5319680eb0c8b9c3f8fefd157534fd90&type=n ...
- Pycharm 2017.1 激活服务器
最近发现pycharm激活异常困难 原来的激活码 都不能用了 so 根据网上 教程 自己建了激活服务器 尝试可用服务器 20170504 测试发现 给需要域名 http://www.05nb.com: ...
- Android NDK之二:创建NativeActivity
转:http://blog.csdn.net/xiruanliuwei/article/details/7560914 Android NDK为我们提供了两种方式来实现我们的native activi ...
- Android开发(八)——Android组件
参考: [1] Android开发教程:理解Intent和Intent Filter.http://liuzhichao.com/p/506.html
- 树型结构递归 实体递归 JSON格式
用递归实现无限级菜单,产品分类,盖楼式评论.留言等功能. 下列代码不能直接使用 CREATE TABLE [dbo].[P_Category]( [Code] [varchar](36) NOT NU ...
- Oracle 安装报错 [INS-06101] IP address of localhost could not be determined 解决方法
安装Oracle 11gR2,报错:[INS-06101] IP address of localhost could not be determined 出现这种错误是因为主机名和/etc/host ...
- 基于jQuery CSS3鼠标点击动画效果
分享基于jQuery CSS3鼠标点击动画效果支持图片或内容滑动,允许设置动画延迟效果.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div class="co ...