在执行主线程的其余部分之前,如何等待异步方法结果?

时间:2017-09-15 13:43:16

标签: c# asynchronous download

我想按顺序下载一个带异步方法的文件 向用户显示下载的实际进度。

using System;
using System.Net;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        public static void downloadFile(string url)
        {
            Object LockObject = new Object();

            using (var client = new WebClient())
            {
                int left = Console.CursorLeft;
                int top = Console.CursorTop;

                client.DownloadProgressChanged += (o, e) =>
                {
                    lock (LockObject)
                    {

                        Console.SetCursorPosition(0, 0);
                        Console.Write(e.ProgressPercentage + "%");

                    }
                };

                client.DownloadFileAsync(new Uri(url), @"c:\asd");
            }
        }
        static void Main(string[] args)
        {
            Task task = Task.Factory.StartNew(() => downloadFile("http://download.lsoft.net/ActiveDataStudioSetup.exe"));
            task.Wait();

            //There can be lots of funcs after download......
            //!!!
            Console.WriteLine("\nIt should be seen ONLY after the full download"); 

            Console.ReadKey();

        }
    }
}

下载程序似乎很好,文件正在获取并且我也看到了它的实际状态,但是在调用该方法之后,一切都将在调用之后立即执行,但是主线程应该等待完成下载第一

1 个答案:

答案 0 :(得分:2)

问题是您的downloadFile方法是异步void方法。该方法只是启动异步操作并立即返回,但它没有提供任何方式通知调用者何时完成。你启动另一个线程中的异步操作,然后等待它在你的main方法中完成启动异步操作,然后再继续没有导致它等待它正在完成下载,正如您所见。

您需要更改下载文件,以便它返回Task,表明它已完成的时间:

public static Task DownloadFile(string url)
{
    using (var client = new WebClient())
    {
        client.DownloadProgressChanged += (o, e) =>
        {
            lock (client)
            {
                Console.SetCursorPosition(0, 0);
                Console.Write(e.ProgressPercentage + "%");
            }
        };
        return client.DownloadFileTaskAsync(new Uri(url), @"c:\asd");
    }
}

然后当然没有理由从另一个线程启动它。您只需调用该方法即可开始下载:

private static void Main()
{
    Task task = DownloadFile("http://download.lsoft.net/ActiveDataStudioSetup.exe");
    task.Wait();

    Console.WriteLine("\nIt should be seen ONLY after the full download");

    Console.WriteLine();
    Console.WriteLine("Press any key to Exit. . . ");
    Console.ReadKey(true);
}