简体   繁体   中英

c# tasks async/await or ContinueWith or?

I call 2 same tasks from main (like this

static void Main()
    {
        Downloads test = new Downloads();
        test.DisplayResultAsync();
        test.DisplayResultAsync();
        Console.WriteLine("main");
        Console.ReadLine();
    }

), where DisplayResultAsync is

        public async Task DisplayResultAsync()
        {

            byte[] result = await DownLoadFile();
            Console.WriteLine("Downloading complete", result[0]);
        }

        static  Task<byte[]> DownLoadFile()
        {
            FileDownLoader flDl = new FileDownLoader();

            return  Task.Run(() =>
            {
                byte[] result = flDl.Download("test"); 
               return result;
            });
        }

I want execute this task in background, but the second task should begin when the first is finished.

FileDownLoader code:

class FileDownLoader
    {
        public byte[] Download(string url)
        {
            Thread.Sleep(2000);
            return new byte[] { 1, 2, 3, 4 };
        }
    } 

what should I use? because this task executing together

A couple issues here. First, you'll want to use asynchronous file I/O to perform the actual file downloads so you're not blocking threads. It appears your FileDownLoader class is just faking it for now, and that's fine but let's at least fake it asynchronously:

class FileDownLoader
{
    public async byte[] DownloadAsync(string url)
    {
        await Task.Delay(2000);
        return new byte[] { 1, 2, 3, 4 };
    }
}

What that allows you to do is get rid of Task.Run in your calling code. (With I/O-bound work like this, async is all about consuming fewer threads, not more. Anytime you see Task.Run in an async method, it's usually a sign you've done something wrong.)

Moving on, you can combine DisplayResultAsync and DownLoadFile into just this:

public async Task DownloadAndDisplayResultAsync()
{
    FileDownLoader flDl = new FileDownLoader();
    byte[] result = await flDl.DownloadAsync("test");
    Console.WriteLine("Downloading complete", result[0]);
}

You want to call the above method twice, but you don't want the second call to start until the first completes. await allows you to do this very easily and without blocking, but you can only do it from an async method (not Main ), so let's introduce a new method in your console app:

static async Task DoWorkAsync()
{
    Downloads test = new Downloads();
    await test.DisplayResultAsync();
    await test.DisplayResultAsync();
}

Now we just need to call it from Main . You said you want the downloads to happen "in the background", so presumably you have some "foreground" work that you want to do concurrently. That goes where commented:

static void Main()
{
    var task = DoWorkAsync();
    // do "foreground" work here
    task.Wait();
    Console.ReadLine();
}

As a side note, another rule of thumb with async code is that you should never block an async call with .Wait() or .Result , except in the Main method of a console app. Use await in all other situations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM