2015-04-07 1 views
-2

Я пытаюсь начать использовать методы async в .net 4.5, и я подумал, что я это понял, но теперь, когда я пытаюсь сделать это в func, но я не могу получить следующее работать:async lambda не возвращается до ожидаемого метода возвращает

Action task = async() => 
    { 

      await _db.SaveChangesAsync(); 
      Debug.WriteLine("Save completed"); 

    }; 

task(); 

Debug.WriteLine("Returned");   

выход будет: Сохранить завершен возвращенный

Я ожидал, что это будет в обратном порядке.

Любые идеи?

Спасибо!

Edit 1:

Я создал образец кода, чтобы показать, что я хочу, и странно то, что она прекрасно работает:

static void Main(string[] args) 
    { 
     using (BCFdbEntities db = new BCFdbEntities()) 
     { 
      IssueComment ic = db.IssueComments.First(); 

      ic.Comment = DateTime.Now.ToString() ; 

      Action a = async() => 
       { 
        await db.SaveChangesAsync(); 

        Console.WriteLine("Save completed"); 

       }; 

      a(); 
      Console.WriteLine("Returned"); 

      Console.ReadLine(); 

     } 



    } 
} 

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

+0

Что вы подразумеваете под словом «Я не могу заставить следующее работать»? Непонятно, чего вы пытаетесь достичь, чего вы ожидаете, что на самом деле происходит, или какого контекста вы находитесь (консольное приложение, веб-приложение, winforms/wpf app). –

+0

Извините, Джон, я случайно отправил его, прежде чем я закончил с ним, пока я добавлял теги. – Erik83

+0

Хорошо, так что делает 'SaveChangesAsync'? (Например, это EF?) Можете ли вы опубликовать короткую, но полную * программу, демонстрирующую проблему? –

ответ

0

Я ожидал, что оно будет в обратном порядке.

Вы ничего не можете ожидать, извините. Это состояние гонки.

Если вы хотите дождаться завершения кода, вы не сможете использовать Action. Вы действительно не должны использовать Action с async lambdas в любом случае, потому что они создают метод async void. И вам следует избегать async void (подробнее в моем MSDN article).

Вместо этого, вы должны использовать async эквивалент Action, который Func<Task> (я описать это более on my blog). С Func<Task>, ваш код вызова теперь await исполнения лямбда в:

Func<Task> task = async() => 
{ 
    await _db.SaveChangesAsync(); 
    Debug.WriteLine("Save completed"); 
}; 

await task(); 
Debug.WriteLine("Returned"); 
+0

Хорошо, я пробовал ваше решение, но у него был тот же результат. Я удалил оператор ожидания, потому что я не хочу ждать задачи, я хочу ждать метода _db.SaveChangesAsync() и не блокировать основной поток. – Erik83

0

Я думаю, что я решил. Сохранение было настолько быстрым, что метод не ожидал. Я добавил Task.Delay (5000), чтобы замедлить его, чтобы убедиться, что это так, и тогда он работал, как ожидалось. После этого я измерил время выполнения, и это всего лишь 12 мс, не совсем уверен в том, как измерить асинхронные методы, поэтому я включил больше кода, чем это могло быть необходимо.

  Stopwatch sw = new Stopwatch(); 
      sw.Start(); 

      Func<Task> task = async() => 
      { 
       // await Task.Delay(5000); 
       await _db.SaveChangesAsync(); 
       Debug.WriteLine("Save completed"); 
      }; 

      task(); 
      Debug.WriteLine("Returned"); 

      sw.Stop(); 

Во всяком случае, я не ожидал, что компилятор, чтобы иметь представление о том, чтобы ждать метод или нет, но apperently это делает.

Спасибо Стивен Клири за предложение о Func вместо Action. Я обязательно буду использовать это в будущем!

Смежные вопросы