这是使4个方法同时异步运行的正确方法吗?

时间:2019-03-21 16:26:30

标签: c# asynchronous

这是使4个方法同时异步运行的正确方法吗?

Version 1:
    public void startup()
    {
        var aTask = Task.Run(async () => {
            Console.WriteLine(Fetchstuff1");
            var data3 = await GetStuff1();
        });

        var bTask = Task.Run(async  () => {
            Console.WriteLine("[Fetchstuff1stuff2");
            var data1= await GetStuff2();
        });

        var cTask = Task.Run(async () => {
            Console.WriteLine(Fetchstuff1stuff3");
            var data2 = GetStuff3();
        });


        Task.WaitAll(aTask, bTask, cTask);

        // DO STUFF AFTER ALL TASK OVER IS DONE
        var categories = GetCategories();
        var dt= CreateDatable();
        Sendtodatabase();
    }


    public async Task<string> Dostuff1,2,3()
    {
        try
        {

            using (HttpResponseMessage result = await _httpClient.GetAsync(Adrdess))
            using (HttpContent content = result.Content)
            {
                result.EnsureSuccessStatusCode();
                string data = await content.ReadAsStringAsync();
            }

            return data;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error"
        }
    }

版本2:

public async Taskstartup()
    {
        await Task.WaitAll(lol());

        // DO STUFF AFTER ALL TASK OVER IS DONE
        var categories = GetCategories();
        var dt= CreateDatable();
        Sendtodatabase();
    }

    private async Task lol() {
        await Task.Run(async () =>
        {
            Console.WriteLine(Fetchstuff1");
            var data3 = await GetStuff1();
            Console.WriteLine("[Fetchstuff1stuff2");
            var data1= await GetStuff2();
            Console.WriteLine(Fetchstuff1stuff3");
            var data2 = GetStuff3();
        });
    }

    public async Task<string> Dostuff1,2,3()
    {
        try
        {

            using (HttpResponseMessage result = await _httpClient.GetAsync(Adrdess))
            using (HttpContent content = result.Content)
            {
                result.EnsureSuccessStatusCode();
                string data = await content.ReadAsStringAsync();
            }

            return data;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error"
        }
    }

版本3:

  public void startup()
    {
            Console.WriteLine(Fetchstuff1");
            var task1= GetStuff1();
            Console.WriteLine("[Fetchstuff1stuff2");
            var task2 = GetStuff2();
            Console.WriteLine(Fetchstuff1stuff3");
            var task3= GetStuff3();

        Task.WhenAll(task1, task2, task3);

        List<String> data1 = await task1;
        List<String> data2 = await task2;
        List<String> data3 = await task3;
            // DO STUFF AFTER ALL TASK OVER IS DONE
            var categories = GetCategories();
            var dt= CreateDatable();
            Sendtodatabase();
        }


        public async Task<string> Dostuff1,2,3()
        {
            try
            {

                using (HttpResponseMessage result = await _httpClient.GetAsync(Adrdess))
                using (HttpContent content = result.Content)
                {
                    result.EnsureSuccessStatusCode();
                    string data = await content.ReadAsStringAsync();
                }

                return data;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error"
            }
        }

我想做的是使a,b,c任务同时运行,因为它们仅检索一些数据。然后,我希望该方法等待所有任务都返回,然后再继续执行该功能,并在所有任务完成后做一些事情。

这是正确完成还是可以更干净的方式进行?我应该使用异步任务启动()吗?我删除了它,因为我没有等待警告的功能。 然后,我希望所有最后的方法在运行时等待。因为像sendtodatabase一样需要在其之前执行dt from方法。

在这种情况下,我的控制台应用程序将执行以下操作:Program.cs中的Main调用启动方法,datapoller方法启动启动,handler方法调用datapoller,getstuff方法调用处理程序。数据轮询器中的方法是一个事件Timer.Elapsed + = DataPollerOnElapsed; 不能设置为异步...位于层次结构的中间。

我该如何解决?

2 个答案:

答案 0 :(得分:1)

不需要Task.Run,​​因为您只包装了已经返回任务的东西。

public async Task StartupAsync()
{
    Console.WriteLine("Fetchstuff1");
    var aTask = GetStuff1Async();

    Console.WriteLine("Fetchstuff1stuff2");
    var bTask = GetStuff2Async();

    Console.WriteLine("Fetchstuff1stuff3");
    var cTask = GetStuff3Async();

    await Task.WhenAll(aTask, bTask, cTask);

    // DO STUFF AFTER ALL TASK OVER IS DONE
    var categories = GetCategories();
    var dt= CreateDatable();
    Sendtodatabase();
}

答案 1 :(得分:0)

这些任务将异步运行,但是您的线程将以Task.WaitAll的形式阻塞,直到所有任务都完成为止。

理想情况下,您应该将启动方法更改为异步(public async Task startup()),并且对其的调用也应该是异步的,以及对该调用的调用等等,直到整个层次结构。

然后,您可以执行await Task.WhenAll(...),这将无阻塞地等待任务完成。

由于您使用的是异步lambda,因此您将强制任务在不同的上下文中运行。有点黑。