柚子快報(bào)激活碼778899分享:C#實(shí)現(xiàn)文件并發(fā)下載
柚子快報(bào)激活碼778899分享:C#實(shí)現(xiàn)文件并發(fā)下載
目錄
1.界面設(shè)計(jì)
2.文件下載功能實(shí)現(xiàn)
2.1定義成員變量
2.2定義DownloadFile()構(gòu)造函數(shù)
2.3定義事件和委托
2.4處理下載狀態(tài)變化的方法
2.5添加一個(gè)下載任務(wù)到線程列表中
2.6啟動(dòng)線程列表中的未啟動(dòng)或已掛起的線程。
2.7執(zhí)行下載操作
3.界面功能實(shí)現(xiàn)
3.1Buttond的功能
3.2Windows窗體的設(shè)計(jì)
3.3事件處理
4.成果展示
5.總結(jié)
1.界面設(shè)計(jì)
????????在界面的設(shè)計(jì)上我使用了VS自帶工具箱中的listView和Button控件。而在listView控件中我進(jìn)行了“編輯列”操作為控件添加了標(biāo)題行。
2.文件下載功能實(shí)現(xiàn)
我創(chuàng)建了一個(gè)新的項(xiàng)目來對(duì)文件下載進(jìn)行編寫
2.1定義成員變量
public int ThreadNum = 3;
List
我使用了一個(gè)變量ThreadNum來確定線程池中同時(shí)運(yùn)行的線程數(shù)量?。并使用一個(gè)列表來存儲(chǔ)和管理多個(gè)線程對(duì)象。
2.2定義DownloadFile()構(gòu)造函數(shù)
public DownLoadFile()
{
doSendMsg += Change;
}
創(chuàng)建DownloadFile類的對(duì)象時(shí),將Change方法添加到doSendMsg事件的處理程序列表中。
2.3定義事件和委托
public delegate void dlgSendMsg(DownMsg msg);
public event dlgSendMsg doSendMsg;
定義了一個(gè)委托dlgSendMsg,用于發(fā)送DownMsg消息。
是一個(gè)事件doSendMsg,它基于dlgSendMsg委托。
2.4處理下載狀態(tài)變化的方法
private void Change(DownMsg msg)
{
if (msg.Tag == DownStatus.Error || msg.Tag == DownStatus.End)
{
StartDown(1);
}
}
檢查傳入的DownMsg對(duì)象msg的Tag屬性是否為DownStatus.Error或DownStatus.End。如果是,則調(diào)用StartDown(1)嘗試啟動(dòng)一個(gè)新的下載線程。
2.5添加一個(gè)下載任務(wù)到線程列表中
public void AddDown(string DownUrl, string Dir, int Id = 0, string FileName = "")
{
Thread tsk = new Thread(() =>
{
download(DownUrl, Dir, FileName, Id);
});
list.Add(tsk);
}
1.創(chuàng)建一個(gè)新的線程實(shí)例tsk,并指定線程要執(zhí)行的代碼塊(調(diào)用download方法)。
2.將新創(chuàng)建的線程實(shí)例tsk添加到線程列表list中。
2.6啟動(dòng)線程列表中的未啟動(dòng)或已掛起的線程。
public void StartDown(int StartNum = 3)
{
for (int i2 = 0; i2 < StartNum; i2++)
{
lock (list)
{
for (int i = 0; i < list.Count; i++)
{
if (list[i].ThreadState == System.Threading.ThreadState.Unstarted || list[i].ThreadState == ThreadState.Suspended)
{
list[i].Start();
break;
}
}
}
}
}
1.循環(huán)StartNum次(默認(rèn)為3)。
2.在每次循環(huán)中,使用lock語句確保線程安全地訪問線程列表list。
3.遍歷線程列表,找到第一個(gè)未啟動(dòng)或已掛起的線程,并啟動(dòng)它。
2.7執(zhí)行下載操作
private void download(string path, string dir, string filename, int id = 0)
{
try
{
DownMsg msg = new DownMsg();
msg.Id = id;
msg.Tag = 0;
doSendMsg(msg);
FileDownloader loader = new FileDownloader(path, dir, filename, ThreadNum);
loader.data.Clear();
msg.Tag = DownStatus.Start;
msg.Length = (int)loader.getFileSize(); ;
doSendMsg(msg);
DownloadProgressListener linstenter = new DownloadProgressListener(msg);
linstenter.doSendMsg = new DownloadProgressListener.dlgSendMsg(doSendMsg);
loader.download(linstenter);
}
catch (Exception ex)
{
DownMsg msg = new DownMsg();
msg.Id = id;
msg.Length = 0;
msg.Tag = DownStatus.Error;
msg.ErrMessage = ex.Message;
doSendMsg(msg);
Console.WriteLine(ex.Message);
}
}
這段代碼實(shí)現(xiàn)了文件下載功能,并可以在下載過程中通過事件通知訂閱者關(guān)于下載的狀態(tài)和進(jìn)度。如果下載過程中發(fā)生錯(cuò)誤,還會(huì)捕獲異常。
3.界面功能實(shí)現(xiàn)
3.1Buttond的功能
private void btnTest_Click(object sender, EventArgs e)
{
string[] lines = File.ReadAllLines("軟件下載1.txt");
for (int i = 0; i < lines.Length; i++)
{
string[] line = lines[i].Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
if (line.Length == 2)
{
string path = Uri.EscapeUriString(line[1]);
string filename = Path.GetFileName(path);
string dir = @"F:\test";
ListViewItem item = listView1.Items.Add(new ListViewItem(new string[] { (listView1.Items.Count + 1).ToString(), filename, "0", "0", "0%", "0", "0", DateTime.Now.ToString(), "等待中", line[1] }));
int id = item.Index;
dlf.AddDown(path, dir, id, id.ToString());
}
}
dlf.StartDown();
}
這段代碼的目的是從文本文件中讀取下載信息,并在listView控件中顯示這些信息,然后啟動(dòng)下載過程。
3.2Windows窗體的設(shè)計(jì)
private void Form1_Load(object sender, EventArgs e)
{
dlf.ThreadNum = 3;//線程數(shù),不設(shè)置默認(rèn)為3
dlf.doSendMsg += SendMsgHander;//下載過程處理事件
}
這段代碼在窗體加載時(shí)設(shè)置了下載管理器dlf的線程數(shù),并注冊(cè)了一個(gè)事件處理程序來響應(yīng)下載過程中的消息。這樣,當(dāng)窗體加載完成后,下載管理器就可以根據(jù)這些設(shè)置和事件處理程序來執(zhí)行和管理下載任務(wù)了。
3.3事件處理
private void SendMsgHander(DownMsg msg)
{
switch (msg.Tag)
{
case DownStatus.Start:
this.Invoke((MethodInvoker)delegate ()
{
listView1.Items[msg.Id].SubItems[8].Text = "開始下載";
listView1.Items[msg.Id].SubItems[7].Text = DateTime.Now.ToString();
});
break;
case DownStatus.GetLength:
this.Invoke((MethodInvoker)delegate ()
{
listView1.Items[msg.Id].SubItems[3].Text = msg.LengthInfo;
listView1.Items[msg.Id].SubItems[8].Text = "連接成功";
});
break;
case DownStatus.End:
case DownStatus.DownLoad:
this.Invoke(new MethodInvoker(() =>
{
this.Invoke((MethodInvoker)delegate ()
{
listView1.Items[msg.Id].SubItems[2].Text = msg.SizeInfo;
listView1.Items[msg.Id].SubItems[4].Text = msg.Progress.ToString() + "%";
listView1.Items[msg.Id].SubItems[5].Text = msg.SpeedInfo;
listView1.Items[msg.Id].SubItems[6].Text = msg.SurplusInfo;
if (msg.Tag == DownStatus.DownLoad)
{
listView1.Items[msg.Id].SubItems[8].Text = "下載中";
}
else
{
listView1.Items[msg.Id].SubItems[8].Text = "下載完成";
}
Application.DoEvents();
});
}));
break;
case DownStatus.Error:
this.Invoke((MethodInvoker)delegate ()
{
listView1.Items[msg.Id].SubItems[6].Text = "失敗";
listView1.Items[msg.Id].SubItems[8].Text = msg.ErrMessage;
Application.DoEvents();
});
break;
}
}
這段代碼的主要作用是處理來自下載管理器的消息,并根據(jù)消息內(nèi)容更新UI中的?listView?控件,以反映下載任務(wù)的當(dāng)前狀態(tài)、進(jìn)度和其他相關(guān)信息。?
4.成果展示
? ? ? ? 可以看到程序能夠正確運(yùn)行。需要提醒以下,在下載第四個(gè)文件時(shí)我故意給了一個(gè)錯(cuò)誤的樣例來驗(yàn)證如果下載出現(xiàn)錯(cuò)誤時(shí)程序會(huì)如何運(yùn)行。
5.完整代碼
巨山超里霸迪卡/Windows程序設(shè)計(jì)課程作業(yè)
6.總結(jié)
????????本C#程序?qū)崿F(xiàn)了一個(gè)功能全面的文件下載工具。該程序從文本文件中讀取下載鏈接和文件名,并通過ListView控件將這些信息直觀地展示給用戶。通過點(diǎn)擊“測(cè)試”按鈕,用戶能夠觸發(fā)多線程下載器開始下載文件。該程序允許用戶自定義線程數(shù),以適應(yīng)不同的網(wǎng)絡(luò)環(huán)境,并實(shí)時(shí)更新ListView中的下載進(jìn)度信息,包括文件大小、下載速度、剩余時(shí)間等關(guān)鍵指標(biāo)。若下載過程中發(fā)生錯(cuò)誤,程序具備自動(dòng)重試下載的功能,確保文件能夠完整下載。該程序不僅展示了C#在多線程編程方面的強(qiáng)大能力,也體現(xiàn)了Windows窗體編程的便捷性和實(shí)用性。通過這個(gè)項(xiàng)目,開發(fā)者能夠深入學(xué)習(xí)C#編程技巧,理解多線程編程的原理,并熟悉處理文件下載等常見應(yīng)用場(chǎng)景的方法,為開發(fā)功能豐富的桌面應(yīng)用程序打下堅(jiān)實(shí)的基礎(chǔ)。
柚子快報(bào)激活碼778899分享:C#實(shí)現(xiàn)文件并發(fā)下載
推薦鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。