Это правильный способ заставить 4 метода работать одновременно асинхронно? - PullRequest
0 голосов
/ 21 марта 2019

Это правильный способ одновременной работы 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 одновременно, поскольку они получают только некоторые данные. Затем я хочу, чтобы метод дождался, пока все задачи вернутся, перед тем как продолжить выполнение функции и выполнить какие-либо действия после того, как все задачи будут выполнены.

Это сделано правильно или я могу сделать это более чистым способом? Должен ли я использовать Async Task Startup ()? Я удалил его, потому что у меня не было функций с ожиданием предупреждения. Затем я хочу, чтобы все последние методы запускались и ждали его запуска. потому что подобно sendtodatabase требуется метод dt from, выполняемый перед ним.

В этой ситуации мое консольное приложение выполняет следующее: вызовы Main в Program.cs для метода запуска, вызов запуска для метода datapoller, вызов метода datapoller для метода-обработчика и вызов обработчика для метода getstuff. Метод в хранилище данных представляет собой событие Timer.Elapsed + = DataPollerOnElapsed; это не может быть установлено на асинхронный ... Что находится в середине иерархии.

Как я могу решить эту проблему?

Ответы [ 2 ]

1 голос
/ 21 марта 2019

Нет необходимости в 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();
}
0 голосов
/ 21 марта 2019

Задачи будут выполняться асинхронно, но ваш поток будет блокироваться как блоки Task.WaitAll, пока все задачи не будут завершены.

В идеале вы должны изменить свой метод запуска на асинхронный (public async Task startup()), и вызов к нему также должен быть асинхронным, и вызов этого и т. Д. По всей иерархии.

Затем вы можете сделать await Task.WhenAll(...), который будет неблокировать ожидание, пока задачи не будут завершены.

Поскольку вы используете асинхронную лямбду, вы заставляете задачи запускаться в другом контексте. Который немного хакерский.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...