解决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限制连接数”. 客户请求的连接内容包括: [ ...
随机推荐
- nginx 前端调度 对后端的app的生存状态的检测
# cat hosts.conf #app调试 upstream gl-appsrv_pools { server 10.1x0.2xx.1x0:8040; server 10.x9x.20.208: ...
- hi模板文件报乱码问题
1.h5模板在: Templates\common 2.出现乱码的都在Templates\common\tags 局部视图里. 3.页面顶部有引用(skin-Common_SubmmitCartPr ...
- latex基本语法
一直想着学会latex,但是自学起来太麻烦,总是出现各种不理解的错误,也没那么多时间钻研,就学了忘,忘了再学,这里就先摘录下它的基本命令吧.学好了是一件利器!(虽然不常用,但要尽量学会) LaTex基 ...
- 21、uwp UI自动化测试(WinAppDriver)
使用 UI自动化测试的好处就是在代码逻辑中写好 case 后,来实现 “一劳永逸” 的作用,并且自动化测试能够模拟人工达不到要求,比如快速切换页面.快速点击按钮等,对于提高软件的稳定性很有帮助. 安装 ...
- 19、UWP 新特性(Creator Update)
Build 版本 15063+ 1.能够为 CompositionObjects 的其他属性(阴影,裁剪,属性集合)添加动画 2.当设备插上电源的时候,通过 Extended Excution Ses ...
- HBase操作(Shell与Java API)
版权声明:本文为博主原创文章,未经博主允许不得转载. 转: http://blog.csdn.net/u013980127/article/details/52443155 下面代码在Hado ...
- System.in的用法
方法1 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));Scanner scanner=new Sca ...
- C# FileStream 文件复制
方法: /// <summary> /// 文件复制 /// </summary> /// <param name="source">源文件,例 ...
- LeetCode: Valid Palindrome 解题报告
Valid Palindrome Given a string, determine if it is a palindrome, considering only alphanumeric char ...
- 第23章 RTX 低功耗之待机模式
以下内容转载自安富莱电子: http://forum.armfly.com/forum.php STM32F103 待机模式介绍 本章节我们主要讲解待机模式,待机模式可实现系统的最低功耗.该模式是在 ...