C#下載歌詞文件的同步和異步方法
前段時間寫了一篇C#解析Lrc歌詞文件,對lrc文件進行解析,支持多個時間段合并。本文借下載歌詞文件來探討一下同步和異步方法。
Lrc文件在網(wǎng)絡(luò)上隨處可見,我們可以通過一些方法獲取,最簡單的就是別人的接口,如: http://geci.me/api/lyric/不得不愛 返回下面的json,這樣我們就很容易得到歌詞文件了。
{
"count": 2,
"code": 0,
"result": [
{
"aid": 2727794,
"lrc": "http://s.geci.me/lrc/327/32793/3279317.lrc",
"song": "不得不愛",
"artist_id": 2,
"sid": 3279317
},
{
"aid": 3048347,
"lrc": "http://s.geci.me/lrc/371/37129/3712941.lrc",
"song": "不得不愛",
"artist_id": 2,
"sid": 3712941
}
]
}
在C#解析Lrc歌詞文件中我們創(chuàng)建了Lrc類,我們繼續(xù)在該類中添加方法。
同步下載實現(xiàn)
創(chuàng)建SearchLrc靜態(tài)方法,該方法實現(xiàn)對歌詞的搜索:首先查看本地文件夾(我的文件夾是D:\lrc\)是否存在lrc文件,如果不存在就下載lrc文件,返回Lrc對象。
public static Lrc SearchLrc(string musicName)
{
string path = @"D:\lrc\" + musicName + ".lrc";
if (System.IO.File.Exists(path))
{
return InitLrc(path);
}
else
{
return DownloadLrc(musicName, path);
}
}
下載歌詞利用WebClient,首先用DownloadString方法將獲取json,再利用JavaScriptSerializer反序列化為自定義對象,這樣就得到了lrc文件的url,最后通過url將lrc文件下載到本地,再調(diào)用InitLrc方法返回Lrc對象。
public class TempJosnMain
{
public int count { get; set; }
public int code { get; set; }
public List<TempJsonChild> result { get; set; }
}
public class TempJsonChild
{
public int aid { get; set; }
public string lrc { get; set; }
public string song { get; set; }
public int artist_id { get; set; }
public int sid { get; set; }
}
static Lrc DownloadLrc(string musicName, string path)
{
if (musicName.Contains("-"))
musicName = musicName.Split('-')[1].Trim();
string url = "http://geci.me/api/lyric/" + musicName;
WebClient wc = new WebClient();
string json = wc.DownloadString(url);
JavaScriptSerializer js = new JavaScriptSerializer();
TempJosnMain res = js.Deserialize<TempJosnMain>(json);
if (res.count > 0)
{
wc.DownloadFile(new Uri(res.result[0].lrc), path);
wc.Dispose();
return InitLrc(path);
}
return new Lrc();
}
異步下載實現(xiàn)
創(chuàng)建SearchLrcAsyc靜態(tài)方法,該方法沒有返回值,所以我們用回調(diào)方法作為參數(shù)(該回調(diào)方法用Lrc作為參數(shù)并且沒有返回值),異步下載主要體現(xiàn)在json數(shù)據(jù)和文件的下載
public static void SearchLrcAsyc(string musicName, Action<Lrc> action)
{
string path = @"D:\lrc\" + musicName + ".lrc";
if (System.IO.File.Exists(path))
{
action(InitLrc(path));
}
else
{
DownloadLrcAsyc(musicName, path, action);
}
}
WebClient的DownloadStringAsync實現(xiàn)異步下載字符串,不會阻止調(diào)用線程。
DownloadStringCompleted事件在下載字符串完成后觸發(fā)。我們可以使用
DownloadStringAsync方法的構(gòu)造來傳遞參數(shù),從而達到在DownloadStringCompleted內(nèi)部調(diào)用我們的Action<Lrc>函數(shù)。而我們的參數(shù)有兩個,所以需要封裝成一個對象。
public void DownloadStringAsync( Uri address, object userToken )
address
包含要下載的 URI 的 Uri。
userToken
一個用戶定義對象,此對象將被傳遞給完成異步操作時所調(diào)用的方法。在DownloadStringCompleted方法中通過e.UserState來獲取
public class CallbackObject
{
public string path { get; set; }
public Action<Lrc> action { get; set; }
}
static void DownloadLrcAsyc(string musicName, string path, Action<Lrc> action)
{
if (musicName.Contains("-"))
musicName = musicName.Split('-')[1].Trim();
string url = "http://geci.me/api/lyric/" + musicName;
WebClient wc = new WebClient();
CallbackObject co = new CallbackObject()
{
action = action,
path = path
};
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
wc.DownloadStringAsync(new Uri(url), co);
}
static void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
JavaScriptSerializer js = new JavaScriptSerializer();
TempJosnMain res = js.Deserialize<TempJosnMain>(e.Result);
if (res.count > 0)
{
WebClient wc = sender as WebClient;
if (wc == null)
wc = new WebClient();
CallbackObject co = e.UserState as CallbackObject;
wc.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(wc_DownloadFileCompleted);
wc.DownloadFileAsync(new Uri(res.result[0].lrc), co.path, co);
}
}
static void wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
CallbackObject co = e.UserState as CallbackObject;
co.action(InitLrc(co.path));
}
最后演示:
點擊下載時會有線程等待感覺像程序”卡死”,而異步下載則非常流暢。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
欄 目:C#教程
下一篇:C#實現(xiàn)一個簡單實用的TXT文本操作及日志框架詳解
本文標題:C#下載歌詞文件的同步和異步方法
本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/5120.html
您可能感興趣的文章


閱讀排行
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現(xiàn)txt定位指定行完整實例
- 01-10WinForm實現(xiàn)仿視頻播放器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機閱讀
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10delphi制作wav文件的方法
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10C#中split用法實例總結(jié)
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 04-02jquery與jsp,用jquery


