线程下载文件C#

时间:2015-01-08 23:17:42

标签: c# multithreading

我遇到线程问题,我有这个代码(例子):

private void button_Click(object sender, EventArgs e) {
    ShowMessage("Starting Downloads...");
    <more code>
    StartDownloads();
    RunFileDownload();
    <more code>
}

private void StartDownloads() {
    <more code>
    for (int i=0; i<10; i++) {
        ShowMessage("Downloading file: " + i);
        Download(i);
        <more code>
    }
    <more code>
}

问题是,当我按下按钮并开始下载时,不会显示消息...我试图用线程修复它,如下所示:

private void button_Click(object sender, EventArgs e) {
    ShowMessage("Starting Downloads...");
    Thread t = new Thread(new ThreadStart(StartDownloads));
    t.Start();
    RunFileDownload();
}

但是RunFileDownload();函数在下载文件之前启动。我尝试使用&#34; Thread.Join();&#34;但同样没有显示消息(主线程已暂停)。

我想用多线程解决它并且Thread.Join();但它没有效率,我将在主线程中遇到其他功能的问题。

我该如何解决这个问题? 感谢。

编辑#2:

考虑此代码:

private void Download() {
    ShowMessage("Starting Downloads...");
    Thread t = new Thread(new ThreadStart(StartDownloads));
    ShowMessage("Downloads Finished...");   | not run until
    RunFileDownload();                      | finished
    ShowMessage("Files Executed...");       | thread.
}

如何在执行其余代码之前完成线程完成? 我尝试使用Thread.Join();但它冻结了应用程序。

1 个答案:

答案 0 :(得分:5)

假设您有权访问async / await,最简单的解决方案就是:

private async void button_Click(object sender, EventArgs e)
{
    ShowMessage("Starting Downloads...");
    await StartDownloads(); //Return control until this method completes!
    RunFileDownload();
}

请注意,await的例外情况就足够了。 请确保您使用正确的try / catch块,尤其是从await开始。请考虑使用此模式:Fire-and-forget with async vs "old async delegate"并阅读此article

请注意StartDownloads需要异步并返回Task才能生效。

除了该解决方案之外,您需要线程在完成时调用回调或引发事件,以便您可以运行RunFileDownload。使用BackgroundWorker可以简化该过程。