解决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限制连接数”. 客户请求的连接内容包括: [ ...
随机推荐
- python代码制作configure文件
在lua中,一直用lua作为config文件,或承载数据的文件 - 好处是lua本身就很好阅读,然后无需额外写解析的代码,还支持在configure文件中读环境变量,条件判断等. 在lua中通过loa ...
- 【Unity】11.6 恒定力 (Constant Force)
分类:Unity.C#.VS2015 创建日期:2016-05-02 一.简介 恒定力 (Constant Force) 是用于向刚体 (Rigidbody) 添加恒定力的快速实用工具,适用于类似火箭 ...
- 【Unity】6.4 Transform--移动、旋转和缩放游戏对象
分类:Unity.C#.VS2015 创建日期:2016-04-20 一.简介 Unity引擎提供了丰富的组件和类库,为游戏开发提供了非常大的便利,熟练掌握和使用这些API,对于游戏开发的效率提高很重 ...
- C#.NET中遍历指定目录下的文件(及所有子目录及子目录里更深层目录里的文件)
//遍历一个目录下所有的文件列表,代码实例 DirectoryInfo dir = new DirectoryInfo(folderName);var list = GetAll(dir); /// ...
- android笔记---主界面(二)自定义actionbar环境的配置
第一步,添加java文件 第二步,添加actionbar的item文件 是个选择器,点中状态和选中状态 <?xml version="1.0" encoding=" ...
- Quantum Computation and Quantum Information
https://www.amazon.com/Quantum-Computation-Information-10th-Anniversary/dp/1107002176/ref=asap_bc?ie ...
- 定期批量修改远程服务器root密码
一.背景 很多时候运维或安全工作人员需要维护大量的服务器,其中就包括判断是否存在root弱口令, 如果服务器数量很多一一修改的话的确是要好花费不少时间精力的.如果通过脚本来实现密码更改, 再做一个定期 ...
- text字段增加处理
--text字段增加处理 --创建测试表 ),detail text) insert into test ','A*B' --定义添加的的字符串 ),@postion int select @s_st ...
- [Windows Azure] Load Testing in Windows Azure
The primary goal of a load test is to simulate many users accessing a web application at the same ti ...
- iOS 减法计算器
一: 在界面上拖入相应的控件 二: 给每个控件设置关联 //监听按钮的点击 - (IBAction)compute:(id)sender; //第一个文本输入框的值 @property (weak, ...