0

Имеется метод, который внутри себя запускает дважды другой метод, но второй раз асинхронно. И вот внутри Task не срабатывает SaveToDB().. Подскажите, пожалуйста в чём моя ошибка

public IEnumerable<UserFeedPrerender> GetFeedPrerenders(int userId, FilterPaging paging)
    {
        var feedPrerenders = PreRenderFeed(userId, paging);

        Task.Run(() =>
        {
            var fullPrerenders = PreRenderFeed(userId, null);
            SaveToDB(fullPrerenders, userId);
        });

        return feedPrerenders;
    }


 public async void SaveToDB(IEnumerable<UserFeedPrerender> userFeedPrerenderElements, int userId)
    {
        await Task.Run(() => SaveSelectedElementsToDB(userFeedPrerenderElements, userId));
    }
Arantler
  • 968
  • 1
    Ну ошибка в том, что вы не дожидаетесь выполнения таска и теряете его. – iluxa1810 Feb 18 '19 at 10:07
  • @iluxa1810, я так понимаю нужно заменить возвращаемый тип с void на Task? –  Feb 18 '19 at 10:09
  • для начала да. Тем не менее, проблема останется. – iluxa1810 Feb 18 '19 at 10:11
  • @iluxa1810, будьте добры - подскажите как исправить её полностью –  Feb 18 '19 at 10:12
  • Попробуй, вместо IEnumerable время Task, поставь модификатор async и через await дождись выполнения таска. – iluxa1810 Feb 18 '19 at 10:17
  • @iluxa1810, Работает, но тогда у меня return срабатывает только после того, как выполняется Task. А я хотел бы чтоб этот Task в фоне работал –  Feb 18 '19 at 11:13

1 Answers1

1

Предположу, что вам надо что то вроде этого

public async Task<IEnumerable<UserFeedPrerender>> GetFeedPrerenders(int userId, FilterPaging paging)
{
    var feedPrerenders = PreRenderFeed(userId, paging);
    await Task.Run(() =>
    {
        var fullPrerenders = PreRenderFeed(userId, null);
        SaveSelectedElementsToDB(fullPrerenders, userId);
    });
    return feedPrerenders;
}

Вариант без асинхронного ожидания (в случае, если вас не волнует ни статус выполнения задачи, ни потенциально возникающие исключения в ней)

public IEnumerable<UserFeedPrerender> GetFeedPrerenders(int userId, FilterPaging paging)
{
    var feedPrerenders = PreRenderFeed(userId, paging);
    Task.Run(() =>
    {
        var fullPrerenders = PreRenderFeed(userId, null);
        SaveSelectedElementsToDB(fullPrerenders, userId);
    });
    return feedPrerenders;
}
tym32167
  • 32,857
  • Тогда ведь не надо асинхронно SaveToDB() вызывать – Roman Ieromenko Feb 18 '19 at 10:53
  • @RomanIeromenko у меня вообще нет метода SaveToDB() – tym32167 Feb 18 '19 at 10:54
  • Да, согласен, был у него – Roman Ieromenko Feb 18 '19 at 10:58
  • Работает, но тогда у меня return срабатывает только после того, как выполняется Task. А я хотел бы чтоб этот Task в фоне работал –  Feb 18 '19 at 11:10
  • Асинхронность от многопоточности отличается почитай https://ru.stackoverflow.com/questions/445768/%D0%9C%D0%BD%D0%BE%D0%B3%D0%BE%D0%BF%D0%BE%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B5-vs-%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D0%BE%D0%B5-%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5 – Roman Ieromenko Feb 18 '19 at 11:18
  • @st4rk добавил вариант без ожидания, но в таком случае вы никак не узнаете, выполнилось ли действие успешно или нет. – tym32167 Feb 18 '19 at 11:19
  • @tym32167, спасибо –  Feb 18 '19 at 11:25
  • @RomanIeromenko, спасибо, прочту –  Feb 18 '19 at 11:25
  • @RomanIeromenko, т.е я могу запустить сохранение в базу данных просто в отдельном потоке, не прибегая к асинхронному программированию? –  Feb 19 '19 at 09:00
  • @st4rk поток - это ценный ресурс, асинхронное программирование позволяет не блокировать поток во время операций с БД, но вы да, можете работать с БД синхронно, блокируя отдельный поток, то есть занимая ресурс, который просто будет ждать ответа от БД – tym32167 Feb 19 '19 at 09:07